Skip to content

Commit 06a4f83

Browse files
jeet1995Copilot
andcommitted
Remove reflection from ensureClassInitialized, fix <clinit> ordering
Replace the reflective initialize() fallback in ensureClassInitialized() with a pure Class.forName() approach. The recursive <clinit> issue in CosmosItemSerializer is fixed by moving 'static { initialize(); }' before the DEFAULT_SERIALIZER field, so the accessor is registered before DefaultCosmosItemSerializer's <clinit> needs it. ensureClassInitialized() is now a clean 3-line method with no reflection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 5e11ce7 commit 06a4f83

File tree

2 files changed

+4
-16
lines changed

2 files changed

+4
-16
lines changed

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
*/
3131
public abstract class CosmosItemSerializer {
3232

33+
// Register the accessor before any static fields that may trigger other classes'
34+
// <clinit> which need this accessor (e.g., DefaultCosmosItemSerializer).
35+
static { initialize(); }
3336

3437
/**
3538
* Gets the default Cosmos item serializer. This serializer is used by default when no custom serializer is
@@ -163,6 +166,4 @@ public ObjectMapper getItemObjectMapper(CosmosItemSerializer serializer) {
163166
}
164167
});
165168
}
166-
167-
static { initialize(); }
168169
}

sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/ImplementationBridgeHelpers.java

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -123,24 +123,11 @@ public static void initializeAllAccessors() {
123123
*/
124124
private static void ensureClassInitialized(String className) {
125125
try {
126-
Class<?> cls = Class.forName(className, true, ImplementationBridgeHelpers.class.getClassLoader());
127-
// Class.forName triggers <clinit> for first-time loading. However, during recursive
128-
// <clinit> from the same thread (e.g., CosmosItemSerializer.<clinit> → DefaultCosmosItemSerializer
129-
// → getCosmosItemSerializerAccessor() → ensureClassInitialized("CosmosItemSerializer")),
130-
// Class.forName is a no-op per JLS §12.4.2. In that case the accessor hasn't been registered
131-
// yet. Calling initialize() as a regular static method IS allowed during recursive <clinit>
132-
// from the same thread and will explicitly register the accessor.
133-
java.lang.reflect.Method initMethod = cls.getDeclaredMethod("initialize");
134-
initMethod.setAccessible(true);
135-
initMethod.invoke(null);
126+
Class.forName(className, true, ImplementationBridgeHelpers.class.getClassLoader());
136127
} catch (ClassNotFoundException e) {
137128
logger.error("Failed to load class for accessor initialization: {}", className, e);
138129
throw new IllegalStateException(
139130
"Unable to load class for accessor initialization: " + className, e);
140-
} catch (NoSuchMethodException e) {
141-
// Not all classes have an initialize() method — Class.forName alone suffices for those
142-
} catch (java.lang.reflect.InvocationTargetException | IllegalAccessException e) {
143-
logger.debug("Could not invoke initialize() on {}: {}", className, e.getMessage());
144131
}
145132
}
146133

0 commit comments

Comments
 (0)