{"record":{"id":"ef9469805e13c87e","repo":"mockito/mockito","slug":"wow-the-class-objectstreamclass-in-the-jdk-don","errorCode":null,"errorMessage":"Wow, the class 'ObjectStreamClass' in the JDK don't have the field 'name',\nthis is definitely a bug in our code as it means the JDK team changed a few internal things.\n\nPlease report an issue with the JDK used, a code sample and a link to download the JDK would be welcome.","messagePattern":"Wow, the class 'ObjectStreamClass' in the JDK don't have the field 'name',\nthis is definitely a bug in our code as it means the JDK team changed a few internal things\\.\n\nPlease report an issue with the JDK used, a code sample and a link to download the JDK would be welcome\\.","errorType":"exception","errorClass":"MockitoSerializationIssue","httpStatus":null,"severity":"error","filePath":"mockito-core/src/main/java/org/mockito/internal/creation/bytebuddy/ByteBuddyCrossClassLoaderSerializationSupport.java","lineNumber":340,"sourceCode":"         * the given <code>ObjectStreamClass</code> to change the name with the newly created class.\n         *\n         * @param descInstance The <code>ObjectStreamClass</code> that will be hacked.\n         * @param proxyClass   The proxy class whose name will be applied.\n         * @throws java.io.InvalidObjectException\n         */\n        private void hackClassNameToMatchNewlyCreatedClass(\n                ObjectStreamClass descInstance, Class<?> proxyClass) throws ObjectStreamException {\n            try {\n                MemberAccessor accessor = Plugins.getMemberAccessor();\n                Field classNameField = descInstance.getClass().getDeclaredField(\"name\");\n                try {\n                    accessor.set(classNameField, descInstance, proxyClass.getCanonicalName());\n                } catch (IllegalAccessException e) {\n                    throw new MockitoSerializationIssue(\n                            \"Access to \" + classNameField + \" was denied\", e);\n                }\n            } catch (NoSuchFieldException nsfe) {\n                throw new MockitoSerializationIssue(\n                        join(\n                                \"Wow, the class 'ObjectStreamClass' in the JDK don't have the field 'name',\",\n                                \"this is definitely a bug in our code as it means the JDK team changed a few internal things.\",\n                                \"\",\n                                \"Please report an issue with the JDK used, a code sample and a link to download the JDK would be welcome.\"),\n                        nsfe);\n            }\n        }\n\n        /**\n         * Read the stream class annotation and identify it as a Mockito mock or not.\n         *\n         * @param marker The marker to identify.\n         * @return <code>true</code> if not marked as a Mockito, <code>false</code> if the class annotation marks a Mockito mock.\n         */\n        private boolean notMarkedAsAMockitoMock(Object marker) {\n            return !MOCKITO_PROXY_MARKER.equals(marker);\n        }","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/mockito/mockito/blob/5a676bcd9ef9a10db46e1dc34e190eb46faa2687/mockito-core/src/main/java/org/mockito/internal/creation/bytebuddy/ByteBuddyCrossClassLoaderSerializationSupport.java#L322-L358","documentation":"Mockito's cross-class-loader serialization support reflects into the JDK-internal class java.io.ObjectStreamClass to overwrite its private 'name' field so a deserialized proxy class matches the newly created class. If reflection reports NoSuchFieldException, the JDK's internal layout changed, so this hack no longer works. Mockito throws MockitoSerializationIssue because this is considered a JDK incompatibility bug rather than a user error.","triggerScenarios":"Deserializing a mock via Mockito's cross-class-loader serialization path when hackClassNameToMatchNewlyCreatedClass (called from resolveClass) looks up ObjectStreamClass.getDeclaredField(\"name\") and the field is missing — i.e. running on a JDK where ObjectStreamClass no longer has the 'name' field.","commonSituations":"Running Mockito on a newer/exotic JDK build where java.io.ObjectStreamClass internals were refactored; using a non-OpenJDK JVM vendor; forward-compatibility break after a JDK upgrade; custom instrumentation/agents that redefine ObjectStreamClass.","solutions":["Check Mockito compatibility with your JDK version and upgrade Mockito to a release supporting your JDK","Report an issue to Mockito with the JDK version, a code sample, and a download link for the JDK","As a workaround, avoid cross-class-loader mock serialization (keep mock creation and deserialization in the same class loader)","Pin to a JDK version where ObjectStreamClass still exposes the 'name' field"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    // deserialize mock across class loaders\n} catch (MockitoSerializationIssue e) {\n    // JDK internals incompatible: log JDK vendor/version, fall back to non-cross-loader usage\n}","preventionTips":["Pin a Mockito version tested against your JDK","Avoid relying on cross-class-loader mock serialization","Keep tests on standard OpenJDK builds","Check Mockito release notes when upgrading the JDK"],"tags":["reflection","jdk-internals","serialization"],"backgroundTag":"jdk-internal-reflection-break","analyzedSha":"5a676bcd9ef9a10db46e1dc34e190eb46faa2687","analyzedAt":"2026-09-05T19:32:58.607Z","contentChangedAt":"2026-09-05T19:32:58.607Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}