Skip to content

Fix JVM <clinit> deadlock by removing static final accessor fields#48689

Open
jeet1995 wants to merge 1 commit intoAzure:mainfrom
jeet1995:fix/clinit-deadlock-bridge-methods
Open

Fix JVM <clinit> deadlock by removing static final accessor fields#48689
jeet1995 wants to merge 1 commit intoAzure:mainfrom
jeet1995:fix/clinit-deadlock-bridge-methods

Conversation

@jeet1995
Copy link
Copy Markdown
Member

@jeet1995 jeet1995 commented Apr 3, 2026

Summary

Fixes a JVM <clinit> deadlock (#48622, #48585) that permanently hangs threads when multiple threads concurrently trigger Cosmos SDK class loading. Also fixes a latent CosmosItemSerializer.DEFAULT_SERIALIZER null bug.

Fixes: #48622, #48585

Root Cause

Deadlock: Consuming classes cached accessors in private static final fields. During <clinit>, the getter calls initializeAllAccessors(), eagerly loading 40+ classes. Concurrent <clinit> of different classes creates circular init-lock waits — permanent deadlock per JLS §12.4.2.

DEFAULT_SERIALIZER null: CosmosItemSerializer.DEFAULT_SERIALIZER cross-referenced DefaultCosmosItemSerializer.DEFAULT_SERIALIZER. When DefaultCosmosItemSerializer.<clinit> ran first, recursive same-thread <clinit> of the parent read the child's field before it was set.

Parent-child <clinit> deadlock: DefaultCosmosItemSerializer.INTERNAL_DEFAULT_SERIALIZER was accessed independently by implementation code, triggering child <clinit> on a different thread than the parent — creating an AB/BA init-lock deadlock between parent and child.

Fix

1. Uniform static getter pattern

// Before — triggers initializeAllAccessors() during <clinit>
private static final FeedResponseAccessor feedResponseAccessor =
    ImplementationBridgeHelpers.FeedResponseHelper.getFeedResponseAccessor();

// After — no <clinit> involvement
private static FeedResponseAccessor feedResponseAccessor() {
    return ImplementationBridgeHelpers.FeedResponseHelper.getFeedResponseAccessor();
}

2. Break CosmosItemSerializer ↔ DefaultCosmosItemSerializer cycle

  • CosmosItemSerializer.DEFAULT_SERIALIZER creates instance directly (no cross-class <clinit>)
  • INTERNAL_DEFAULT_SERIALIZER moved from DefaultCosmosItemSerializer to CosmosItemSerializer (private, exposed via CosmosItemSerializerAccessor.getInternalDefaultSerializer())
  • static { initialize(); } placed before DEFAULT_SERIALIZER so accessor is registered before construction — eliminates initializeAllAccessors() fallback during <clinit>
  • DefaultCosmosItemSerializer.DEFAULT_SERIALIZER and its serializationInclusionModeAwareObjectMapper removed (dead code)

Scope

Category Description
Static final/instance accessor fields removed 49 fields across consuming classes
Static getter methods added ~90 private static XxxAccessor xxx() methods
Inline accessor calls replaced ~200 ImplementationBridgeHelpers...getXxxAccessor() → short getter
Missing static { initialize(); } added CosmosRequestContext, CosmosOperationDetails, CosmosDiagnosticsContext
Accessor rename fix getCosmosAsyncClientAccessor()getCosmosDiagnosticsThresholdsAccessor() in CosmosDiagnosticsThresholdsHelper
checkNotNull bug fix DefaultCosmosItemSerializer constructor passed string literal instead of parameter
Files changed 85

Exceptions (not converted to static getters)

  • HttpClient.java — Java 8 interface, no private static methods
  • Utils.javaensureItemSerializerAccessor() uses CAS caching pattern
  • Bridge classes — accessor registration sources, not consumers

Tests

Test What it proves
concurrentAccessorInitializationShouldNotDeadlock (×5 invocations) Forked JVMs with 12 concurrent threads triggering <clinit> — catches deadlock via 30s timeout
allAccessorClassesMustHaveStaticInitializerBlock Forked JVM verifies every accessor is non-null after <clinit>
noStaticOrInstanceAccessorFieldsInConsumingClasses Reflection scan: fails if any class has a static or final Accessor field
accessorInitialization Validates initializeAllAccessors() bootstrap path

Local verification

  • 50/50 deadlock probe passes on JDK 21 + Ubuntu (WSL) with 8 concurrent threads
  • 122/122 spring-data-cosmos tests pass on JDK 17 (Windows) and JDK 21 (Ubuntu)
  • DEFAULT_SERIALIZER non-null in all class-loading orders (verified with reverse-order access)

@github-actions github-actions bot added azure-spring All azure-spring related issues Cosmos labels Apr 3, 2026
@jeet1995
Copy link
Copy Markdown
Member Author

jeet1995 commented Apr 3, 2026

Closing — bridge classes don't allow adding new methods. Proceeding with #48667 (Class.forName with explicit classloader).

@jeet1995 jeet1995 closed this Apr 3, 2026
@jeet1995 jeet1995 reopened this Apr 3, 2026
@jeet1995 jeet1995 force-pushed the fix/clinit-deadlock-bridge-methods branch from e57066d to 66afd43 Compare April 4, 2026 00:05
@jeet1995 jeet1995 changed the title Fix JVM <clinit> deadlock using targeted bridge methods (alternative to #48667) Fix JVM <clinit> deadlock by removing static final accessor fields (alternative to #48667) Apr 4, 2026
@jeet1995 jeet1995 marked this pull request as ready for review April 5, 2026 00:30
Copilot AI review requested due to automatic review settings April 5, 2026 00:30
@jeet1995 jeet1995 changed the title Fix JVM <clinit> deadlock by removing static final accessor fields (alternative to #48667) Fix JVM <clinit> deadlock by removing static final accessor fields Apr 5, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a JVM <clinit> deadlock in the Cosmos Java SDK by removing many static final ...Accessor caches in consuming classes and switching call sites to resolve accessors lazily via ImplementationBridgeHelpers.*Helper.get*Accessor() on demand, reducing class-initialization-time cross-dependencies.

Changes:

  • Replaced numerous private static final XxxAccessor ... = getXxxAccessor() fields with inline (lazy) getter calls at usage sites.
  • Added/adjusted static { initialize(); } blocks and <clinit> ordering to ensure accessors are registered safely during class initialization where required.
  • Added forked-JVM regression/enforcement tests around concurrent <clinit> behavior and accessor registration.

Reviewed changes

Copilot reviewed 54 out of 54 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
sdk/spring/azure-spring-data-cosmos/README.md Trailing whitespace/newline adjustment.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/util/CosmosPagedFluxStaticListImpl.java Removed static accessor cache; inline FeedResponse accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/util/CosmosPagedFluxDefaultImpl.java Removed static accessor cache; inline diagnostics context accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/models/FeedResponse.java Removed static diagnostics accessor cache; inline accessor calls.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/models/CosmosOperationDetails.java Added static { initialize(); } registration block.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/models/CosmosItemRequestOptions.java Removed static thresholds accessor cache; inline thresholds accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/StaleResourceRetryPolicy.java Removed static exception accessor cache.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/SessionTokenMismatchRetryPolicy.java Removed static accessor cache; inline session retry options accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentClientImpl.java Removed multiple static accessor caches; inline accessor usage across implementation.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/QueryPlanRetriever.java Removed static accessor caches; inline accessors for options/exception handling.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/PipelinedQueryExecutionContext.java Removed static accessor cache; inline accessor usage when cloning options.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/PipelinedDocumentQueryExecutionContext.java Removed static accessor caches; inline options and serializer accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/ParallelDocumentQueryExecutionContext.java Removed static accessor caches; inline options/diagnostics accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/OrderByUtils.java Removed static diagnostics accessor cache; inline diagnostics accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/OrderByDocumentQueryExecutionContext.java Removed static accessor caches; inline feed/diagnostics accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/OrderByDocumentProducer.java Removed static feed accessor cache; inline feed accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/NonStreamingOrderByUtils.java Removed static diagnostics accessor cache; inline diagnostics accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/NonStreamingOrderByDocumentQueryExecutionContext.java Removed static accessor caches; inline feed/diagnostics accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/HybridSearchDocumentQueryExecutionContext.java Removed static accessor caches; inline feed/diagnostics accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/GroupByDocumentQueryExecutionContext.java Removed static diagnostics accessor cache; inline diagnostics accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/Fetcher.java Removed static diagnostics accessor cache; inline diagnostics accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/DocumentQueryExecutionContextFactory.java Inline options accessor usage in creation flow.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/DocumentQueryExecutionContextBase.java Removed static accessor caches; inline accessor usage for request creation and cloning.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/DocumentProducer.java Removed static accessor cache; inline accessor usage when cloning options.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/DefaultDocumentQueryExecutionContext.java Removed static accessor cache; inline accessor usage for partition key definition/properties.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/DCountDocumentQueryExecutionContext.java Removed static diagnostics accessor cache; inline diagnostics accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/ChangeFeedFetcher.java Removed static feed accessor cache; inline feed accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/AggregateDocumentQueryExecutionContext.java Removed static accessor caches; inline feed/diagnostics accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/JsonSerializable.java Removed static serializer accessor cache; inline serializer accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/ImplementationBridgeHelpers.java Renamed thresholds accessor getter (getCosmosAsyncClientAccessorgetCosmosDiagnosticsThresholdsAccessor).
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/http/HttpClientConfig.java Removed static HTTP2 config accessor cache; inline accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/Document.java Removed static serializer accessor cache; inline serializer accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/GoneAndRetryWithRetryPolicy.java Removed static exception accessor cache; inline exception accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/DiagnosticsProvider.java Removed multiple static accessor caches; inline accessors throughout tracing/metrics paths.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/CosmosQueryRequestOptionsImpl.java Updated thresholds accessor getter name usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/CosmosQueryRequestOptionsBase.java Updated thresholds accessor getter name usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/ConnectionPolicy.java Removed static HTTP2 config accessor cache; inline accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/clienttelemetry/ClientTelemetryMetrics.java Removed static accessor caches; inline accessors for telemetry metrics recording.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/clienttelemetry/ClientMetricsDiagnosticsHandler.java Removed static telemetry config accessor cache.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/ChangeFeedQueryImpl.java Removed static accessor caches; inline accessors for change feed request/response.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/caches/RxCollectionCache.java Removed static exception accessor cache; inline exception accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/batch/TransactionalBulkExecutor.java Removed static batch request options accessor cache; inline accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/batch/BulkExecutor.java Removed static accessor caches; inline accessors for batch response and diagnostics provider.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosRequestContext.java Added static { initialize(); } registration block.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosItemSerializer.java Reordered <clinit> to register accessor before static fields.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosDiagnosticsContext.java Added static { initialize(); } registration block.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosContainerProactiveInitConfig.java Removed static container identity accessor cache; inline accessor usage.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosAsyncUser.java Removed static accessor caches; inline accessors for query naming/feed response creation.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosAsyncScripts.java Removed static accessor caches; inline accessors for query naming/feed response creation.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosAsyncDatabase.java Removed static accessor caches; inline accessors for query naming/feed response creation.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosAsyncContainer.java Removed many static accessor caches; inline accessors across request/response, policies, and telemetry.
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosAsyncClient.java Removed static accessor caches; inline telemetry/options/feed response accessors.
sdk/cosmos/azure-cosmos/CHANGELOG.md Added changelog bullet for <clinit> deadlock fix.
sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/ImplementationBridgeHelpersTest.java Added forked-JVM deadlock regression test and accessor registration enforcement test.

Comment on lines 57 to 61
@@ -59,7 +59,6 @@ public class DocumentQueryExecutionContextFactory {

private final static int PageSizeFactorForTop = 5;
private static final Logger logger = LoggerFactory.getLogger(DocumentQueryExecutionContextFactory.class);
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DocumentQueryExecutionContextFactory still has a static final CosmosQueryRequestOptionsAccessor (qryOptAccessor) that is initialized during this class’ <clinit> via getCosmosQueryRequestOptionsAccessor(). This reintroduces the class-initialization-time accessor resolution pattern this PR is trying to eliminate and can put initializeAllAccessors() back on a <clinit> path. Please remove this static accessor field and resolve the accessor lazily at the point of use (e.g., inline getter call or a method-local variable).

Copilot uses AI. Check for mistakes.
Comment on lines 31 to 34
public abstract class CosmosQueryRequestOptionsBase<T extends CosmosQueryRequestOptionsBase<?>> implements OverridableRequestOptions {
private final static ImplementationBridgeHelpers.CosmosDiagnosticsThresholdsHelper.CosmosDiagnosticsThresholdsAccessor thresholdsAccessor =
ImplementationBridgeHelpers.CosmosDiagnosticsThresholdsHelper.getCosmosAsyncClientAccessor();
ImplementationBridgeHelpers.CosmosDiagnosticsThresholdsHelper.getCosmosDiagnosticsThresholdsAccessor();

Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CosmosQueryRequestOptionsBase still initializes thresholdsAccessor as a static final field by calling getCosmosDiagnosticsThresholdsAccessor() during class initialization. This is the same pattern that can trigger accessor initialization during <clinit> and can reintroduce the deadlock this PR is addressing. Please remove this static field and resolve the accessor lazily (inline call or method-local caching) where it’s needed.

Copilot uses AI. Check for mistakes.
Comment on lines 15 to 18
public final class CosmosQueryRequestOptionsImpl extends CosmosQueryRequestOptionsBase<CosmosQueryRequestOptionsImpl> {
private final static ImplementationBridgeHelpers.CosmosDiagnosticsThresholdsHelper.CosmosDiagnosticsThresholdsAccessor thresholdsAccessor =
ImplementationBridgeHelpers.CosmosDiagnosticsThresholdsHelper.getCosmosAsyncClientAccessor();
ImplementationBridgeHelpers.CosmosDiagnosticsThresholdsHelper.getCosmosDiagnosticsThresholdsAccessor();
private String partitionKeyRangeId;
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CosmosQueryRequestOptionsImpl still initializes thresholdsAccessor as a static final field by calling getCosmosDiagnosticsThresholdsAccessor() during <clinit>. This keeps accessor resolution on a class-initialization path and can reintroduce the deadlock scenario. Please remove this static field and resolve the accessor lazily at the call sites (optionally cache in a method-local variable).

Copilot uses AI. Check for mistakes.
Comment on lines +289 to +293
* Enforces that every class targeted by {@code ensureClassInitialized()} in
* {@link ImplementationBridgeHelpers} registers its accessor during {@code <clinit>}
* (i.e., has a {@code static { initialize(); }} block).
* <p>
* Verification is behavioral, not source-based: a forked child JVM iterates every
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JavaDoc for allAccessorClassesMustHaveStaticInitializerBlock refers to ensureClassInitialized() and claims the getter triggers Class.forName()<clinit> and will fail if static { initialize(); } is missing. In the current ImplementationBridgeHelpers implementation, getters call initializeAllAccessors() (not a targeted Class.forName()), so this test can pass even when a class doesn’t register its accessor during <clinit> (because initializeAllAccessors() can set accessors directly). Please adjust the test (or the infrastructure) so it actually enforces the intended contract.

Copilot uses AI. Check for mistakes.
Comment on lines +121 to +126
* timeout detects the hang. Runs 5 invocations via TestNG ({@code invocationCount = 5}),
* each forking 3 child JVMs — totaling 15 fresh JVMs × 12 concurrent threads = 180
* {@code <clinit>} race attempts.
*/
@Test(groups = { "unit" }, invocationCount = 5)
public void concurrentAccessorInitializationShouldNotDeadlock() throws Exception {
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

concurrentAccessorInitializationShouldNotDeadlock is marked as a unit test but forks multiple child JVMs (invocationCount=5 and an inner runs=3, i.e., 15 JVM forks per test execution). This is likely to add substantial runtime/overhead to the unit test suite and increase flakiness on constrained CI agents. Consider moving this to a heavier-weight test group (or reducing the fork count) while keeping the regression coverage.

Copilot uses AI. Check for mistakes.
Comment on lines +41 to +44
this.maxRetryAttemptsInCurrentRegion =
new AtomicInteger(sessionRetryOptionsAccessor.getMaxInRegionRetryCount(sessionRetryOptions));
this.regionSwitchHint = sessionRetryOptionsAccessor.getRegionSwitchHint(sessionRetryOptions);
this.minInRegionRetryTime = sessionRetryOptionsAccessor.getMinInRegionRetryTime(sessionRetryOptions);
new AtomicInteger(ImplementationBridgeHelpers.CosmosSessionRetryOptionsHelper.getCosmosSessionRetryOptionsAccessor().getMaxInRegionRetryCount(sessionRetryOptions));
this.regionSwitchHint = ImplementationBridgeHelpers.CosmosSessionRetryOptionsHelper.getCosmosSessionRetryOptionsAccessor().getRegionSwitchHint(sessionRetryOptions);
this.minInRegionRetryTime = ImplementationBridgeHelpers.CosmosSessionRetryOptionsHelper.getCosmosSessionRetryOptionsAccessor().getMinInRegionRetryTime(sessionRetryOptions);
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These inlined accessor calls create very long lines (likely exceeding the 120-character Checkstyle LineLength limit) and are harder to read. Consider storing the accessor in a method-local variable (safe w.r.t. <clinit> deadlock) and/or wrapping the call chain across lines to satisfy the repository’s Checkstyle line-length rule (e.g., eng/lintingconfigs/checkstyle/track2/checkstyle.xml).

Copilot uses AI. Check for mistakes.
Comment on lines 669 to 672
public CosmosDiagnostics createDiagnostics() {
CosmosDiagnostics diagnostics =
diagnosticsAccessor.create(this, telemetryCfgAccessor.getSamplingRate(this.clientTelemetryConfig));
ImplementationBridgeHelpers.CosmosDiagnosticsHelper.getCosmosDiagnosticsAccessor().create(this, ImplementationBridgeHelpers.CosmosClientTelemetryConfigHelper.getCosmosClientTelemetryConfigAccessor().getSamplingRate(this.clientTelemetryConfig));

Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is extremely long due to nested inline accessor calls and is likely to violate the 120-character Checkstyle LineLength rule. Please wrap this across multiple lines and/or use a method-local variable for the accessors to keep the code readable and compliant.

Copilot uses AI. Check for mistakes.
Comment on lines 213 to 216
Duration.ofNanos(feedResponseConsumerLatencyInNanos.get()));

tracerProvider.endSpan(ctxSnapshot, traceCtx, ctxAccessor.isEmptyCompletion(ctxSnapshot), isSampledOut);
tracerProvider.endSpan(ctxSnapshot, traceCtx, ImplementationBridgeHelpers.CosmosDiagnosticsContextHelper.getCosmosDiagnosticsContextAccessor().isEmptyCompletion(ctxSnapshot), isSampledOut);

Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The endSpan call inlines another getCosmosDiagnosticsContextAccessor() invocation, making the line very long and repeating the accessor lookup. Please store the accessor (or isEmptyCompletion result) in a local variable and/or wrap the call across lines to avoid Checkstyle LineLength violations and reduce repeated volatile reads.

Copilot uses AI. Check for mistakes.
Comment on lines +9 to +11
#### Bugs Fixed
Fixing an NPE caused due to boxed Boolean conversion. - See [PR 48656](https://github.com/Azure/azure-sdk-for-java/pull/48656/)
* Fixing an NPE caused due to boxed Boolean conversion. - See [PR 48656](https://github.com/Azure/azure-sdk-for-java/pull/48656/)
* Fixed JVM `<clinit>` deadlock when multiple threads concurrently trigger Cosmos SDK class loading for the first time. - See [PR 48667](https://github.com/Azure/azure-sdk-for-java/pull/48667)
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changelog entry for the <clinit> deadlock fix points to PR #48667, but this PR is described as an alternative approach. Please update the reference to point to the correct PR (this one) or otherwise clarify which change actually delivered the fix in this release line.

Copilot uses AI. Check for mistakes.
jeet1995 added a commit to jeet1995/azure-sdk-for-java that referenced this pull request Apr 5, 2026
… stale docs

- Removed remaining static final accessor fields in
  DocumentQueryExecutionContextFactory, CosmosQueryRequestOptionsBase,
  CosmosQueryRequestOptionsImpl
- Extracted local variables for long inline accessor chains in
  SessionTokenMismatchRetryPolicy, RxDocumentClientImpl,
  CosmosPagedFluxDefaultImpl
- Updated test Javadoc to reflect lazy accessor approach (not Class.forName)
- Reduced child JVM runs from 3 to 1 (invocationCount=5 provides repetition)
- Fixed CHANGELOG PR link to Azure#48689

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jeet1995 jeet1995 force-pushed the fix/clinit-deadlock-bridge-methods branch from 4e41bc9 to 101efda Compare April 7, 2026 22:08
jeet1995 added a commit to jeet1995/azure-sdk-for-java that referenced this pull request Apr 7, 2026
… stale docs

- Removed remaining static final accessor fields in
  DocumentQueryExecutionContextFactory, CosmosQueryRequestOptionsBase,
  CosmosQueryRequestOptionsImpl
- Extracted local variables for long inline accessor chains in
  SessionTokenMismatchRetryPolicy, RxDocumentClientImpl,
  CosmosPagedFluxDefaultImpl
- Updated test Javadoc to reflect lazy accessor approach (not Class.forName)
- Reduced child JVM runs from 3 to 1 (invocationCount=5 provides repetition)
- Fixed CHANGELOG PR link to Azure#48689

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jeet1995 jeet1995 force-pushed the fix/clinit-deadlock-bridge-methods branch 5 times, most recently from d8edfe4 to 7332533 Compare April 8, 2026 00:43
@rujche rujche requested a review from Copilot April 8, 2026 00:57
@Azure Azure deleted a comment from azure-pipelines bot Apr 8, 2026
@Azure Azure deleted a comment from azure-pipelines bot Apr 8, 2026
@Azure Azure deleted a comment from azure-pipelines bot Apr 8, 2026
@Azure Azure deleted a comment from azure-pipelines bot Apr 8, 2026
@Azure Azure deleted a comment from azure-pipelines bot Apr 8, 2026
@Azure Azure deleted a comment from azure-pipelines bot Apr 8, 2026
@Azure Azure deleted a comment from azure-pipelines bot Apr 8, 2026
@Azure Azure deleted a comment from azure-pipelines bot Apr 8, 2026
@Azure Azure deleted a comment from azure-pipelines bot Apr 8, 2026
@Azure Azure deleted a comment from azure-pipelines bot Apr 8, 2026
@Azure Azure deleted a comment from azure-pipelines bot Apr 8, 2026
@Azure Azure deleted a comment from azure-pipelines bot Apr 8, 2026
@Azure Azure deleted a comment from azure-pipelines bot Apr 8, 2026
@Azure Azure deleted a comment from azure-pipelines bot Apr 8, 2026
@Azure Azure deleted a comment from azure-pipelines bot Apr 8, 2026
@Azure Azure deleted a comment from azure-pipelines bot Apr 8, 2026
@jeet1995
Copy link
Copy Markdown
Member Author

@sdkReviewAgent-2

@xinlian12
Copy link
Copy Markdown
Member

Review complete (16:30)

No new comments — existing review coverage is sufficient.

Steps: architecture, context, cross-sdk, history, past-prs, quality, sanity-check, test-coverage

@xinlian12
Copy link
Copy Markdown
Member

@sdkReviewAgent-2

… null

Fixes Azure#48622, Azure#48585

Replace all static final accessor fields and inline
ImplementationBridgeHelpers calls with uniform private static getter
methods. This eliminates <clinit>-time class loading that caused
permanent deadlocks under concurrent class initialization (JLS 12.4.2).

Fix CosmosItemSerializer.DEFAULT_SERIALIZER circular <clinit> —
create instance directly and move INTERNAL_DEFAULT_SERIALIZER to
parent class to prevent concurrent <clinit> between parent and child.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jeet1995
Copy link
Copy Markdown
Member Author

/azp run java - cosmos - ci

@jeet1995
Copy link
Copy Markdown
Member Author

/azp run java - cosmos - tests

@jeet1995
Copy link
Copy Markdown
Member Author

/azp run java - cosmos - kafka

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

@jeet1995
Copy link
Copy Markdown
Member Author

/azp run java - cosmos - spark

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

@jeet1995
Copy link
Copy Markdown
Member Author

/azp run java - spring - ci

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

2 similar comments
@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

azure-spring All azure-spring related issues Cosmos

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants