RFR: 8368182: AOT cache creation fails with class defined by JNI

Ioi Lam iklam at openjdk.org
Tue Sep 23 04:16:21 UTC 2025


On Mon, 22 Sep 2025 07:39:49 GMT, David Holmes <dholmes at openjdk.org> wrote:

> So where were these JNI defined classes originating from when you saw the failures?

We found this bug with an internal test case that uses a JNI library.

> src/hotspot/share/classfile/classLoader.cpp line 1196:
> 
>> 1194:   if (src == nullptr) {
>> 1195:     if (loader == nullptr) {
>> 1196:       // JFR classes
> 
> What was this referring to? I traced this back to "8186842: Use Java class loaders for creating the CDS archive" but no mention of any JFR classes was made. FWIW I can't see any use of JNI DefineClass in the JDK code, so this change would only affect end-user code.

JFR doesn't call JNI DefineClass. Instead, it uses `ClassFileStream` and `ClassFileParser` directly, so it can accomplish the same thing (defining a class with a NULL code source).

The above was written when JFR was defining classes with a with a NULL code source:

https://github.com/openjdk/jdk/blob/02f895c5f6f6de38549337d45ed8ba4c446e9677/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp#L1165

JFR has since been updated to pass a non-null code source to `ClassFileStream`, so the comment about JFR classes is no longer valid.

> test/hotspot/jtreg/runtime/cds/appcds/aotCache/JNIDefineClass.java line 134:
> 
>> 132: }
>> 133: 
>> 134: // This class is loaded into the bootstrap loader using JNI_DEfineClass() with a null code source,
> 
> Suggestion:
> 
> // This class is loaded into the bootstrap loader using JNI_DefineClass() with a null code source,
> 
> Suggestion:
> 
> // This class is loaded into the bootstrap loader using JNI_DEfineClass() with a null code source,

I changed to `JNI DefineClass`, as we don't actually have a C++ symbol of `JNI_DefineClass`.

> test/hotspot/jtreg/runtime/cds/appcds/aotCache/libJNIDefineClassApp.c line 34:
> 
>> 32:     jclass returnValue = (*env)->DefineClass(env, classNameChar, classLoader, arrayContent, bytecodeLength);
>> 33:     (*env)->ReleaseByteArrayElements(env, bytecode, arrayContent, JNI_ABORT);
>> 34:     (*env)->ReleaseStringUTFChars(env, className, classNameChar);
> 
> Does this pass `-Xcheck:jni`? ie. do you need to check for exceptions in the above sequence.

I copied the code from here. Is this style OK for jtreg tests?

https://github.com/openjdk/jdk/blob/61c5245bf7d6626b0c816612adcb0d94d6863644/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/libdefine.cpp#L44-L52

-------------

PR Comment: https://git.openjdk.org/jdk/pull/27412#issuecomment-3322349826
PR Review Comment: https://git.openjdk.org/jdk/pull/27412#discussion_r2371075678
PR Review Comment: https://git.openjdk.org/jdk/pull/27412#discussion_r2371075738
PR Review Comment: https://git.openjdk.org/jdk/pull/27412#discussion_r2371075953


More information about the hotspot-runtime-dev mailing list