Skip to content

Commit 96a042f

Browse files
jeet1995Copilot
andcommitted
Address review: add missing static{initialize()} blocks, improve test
- Add 'static { initialize(); }' to CosmosRequestContext, CosmosOperationDetails, and CosmosDiagnosticsContext which had initialize() methods but no <clinit> invocation, so Class.forName() alone would not register their accessors. - Improve regression test: assert accessor return values are non-null, catch ExecutionException for clearer failure messages, and document the inherent <clinit>-once-per-JVM limitation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent cd14443 commit 96a042f

4 files changed

Lines changed: 22 additions & 9 deletions

File tree

sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/ImplementationBridgeHelpersTest.java

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,13 @@ public void concurrentAccessorInitializationShouldNotDeadlock() throws Exception
116116
// and https://github.com/Azure/azure-sdk-for-java/issues/48585
117117
//
118118
// Verifies that concurrently calling different getXxxAccessor() methods from
119-
// multiple threads completes without deadlock. Before the fix, each getter
120-
// called initializeAllAccessors() which eagerly loaded 40+ classes, creating
121-
// circular <clinit> dependencies that permanently deadlocked the JVM.
119+
// multiple threads completes without deadlock and returns non-null accessors.
120+
//
121+
// Limitation: Since JVM <clinit> runs exactly once per class per JVM lifetime,
122+
// this in-process test validates accessor re-registration after a reflection
123+
// reset — not the actual first-load <clinit> deadlock scenario. The real
124+
// deadlock validation was performed via a 50-run fresh-JVM stress test
125+
// documented in the PR description.
122126

123127
// Reset all accessors to force re-initialization
124128
Class<?>[] declaredClasses = ImplementationBridgeHelpers.class.getDeclaredClasses();
@@ -150,27 +154,27 @@ public void concurrentAccessorInitializationShouldNotDeadlock() throws Exception
150154
// Each thread triggers a different accessor getter concurrently
151155
futures.add(executor.submit(() -> {
152156
awaitBarrier(barrier);
153-
ImplementationBridgeHelpers.CosmosAsyncClientHelper.getCosmosAsyncClientAccessor();
157+
assertThat(ImplementationBridgeHelpers.CosmosAsyncClientHelper.getCosmosAsyncClientAccessor()).isNotNull();
154158
}));
155159
futures.add(executor.submit(() -> {
156160
awaitBarrier(barrier);
157-
ImplementationBridgeHelpers.CosmosItemRequestOptionsHelper.getCosmosItemRequestOptionsAccessor();
161+
assertThat(ImplementationBridgeHelpers.CosmosItemRequestOptionsHelper.getCosmosItemRequestOptionsAccessor()).isNotNull();
158162
}));
159163
futures.add(executor.submit(() -> {
160164
awaitBarrier(barrier);
161-
ImplementationBridgeHelpers.FeedResponseHelper.getFeedResponseAccessor();
165+
assertThat(ImplementationBridgeHelpers.FeedResponseHelper.getFeedResponseAccessor()).isNotNull();
162166
}));
163167
futures.add(executor.submit(() -> {
164168
awaitBarrier(barrier);
165-
ImplementationBridgeHelpers.CosmosQueryRequestOptionsHelper.getCosmosQueryRequestOptionsAccessor();
169+
assertThat(ImplementationBridgeHelpers.CosmosQueryRequestOptionsHelper.getCosmosQueryRequestOptionsAccessor()).isNotNull();
166170
}));
167171
futures.add(executor.submit(() -> {
168172
awaitBarrier(barrier);
169-
ImplementationBridgeHelpers.CosmosAsyncContainerHelper.getCosmosAsyncContainerAccessor();
173+
assertThat(ImplementationBridgeHelpers.CosmosAsyncContainerHelper.getCosmosAsyncContainerAccessor()).isNotNull();
170174
}));
171175
futures.add(executor.submit(() -> {
172176
awaitBarrier(barrier);
173-
ImplementationBridgeHelpers.CosmosItemSerializerHelper.getCosmosItemSerializerAccessor();
177+
assertThat(ImplementationBridgeHelpers.CosmosItemSerializerHelper.getCosmosItemSerializerAccessor()).isNotNull();
174178
}));
175179

176180
boolean deadlockDetected = false;
@@ -180,6 +184,9 @@ public void concurrentAccessorInitializationShouldNotDeadlock() throws Exception
180184
} catch (TimeoutException e) {
181185
deadlockDetected = true;
182186
logger.error("Thread {} did not complete within {} seconds - possible deadlock", i, timeoutSeconds);
187+
} catch (java.util.concurrent.ExecutionException e) {
188+
logger.error("Thread {} threw exception: {}", i, e.getCause().getMessage());
189+
fail("Unexpected exception in thread " + i + ": " + e.getCause());
183190
}
184191
}
185192

sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosDiagnosticsContext.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,4 +1201,6 @@ public Integer getTargetMaxMicroBatchSize(CosmosDiagnosticsContext ctx) {
12011201
}
12021202
});
12031203
}
1204+
1205+
static { initialize(); }
12041206
}

sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/CosmosRequestContext.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,4 +217,6 @@ public CosmosRequestContext create(OverridableRequestOptions requestOptions) {
217217
}
218218
);
219219
}
220+
221+
static { initialize(); }
220222
}

sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/models/CosmosOperationDetails.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,6 @@ static void initialize() {
5656
.setCosmosOperationDetailsAccessor(
5757
CosmosOperationDetails::new);
5858
}
59+
60+
static { initialize(); }
5961
}

0 commit comments

Comments
 (0)