JVMTI GetClassFields and GetClassMethods calls return
respectively arrays of jfieldIDs and jmethodIDs without triggering
class initialization.
These jfieldIDs and jmethodIDs are shared with JNI.
JNI GetFieldID and GetMethodID trigger class initialization prior to returning the jfieldIDs and jmethodIDs.
jfieldIDs and jmethodIDs can be used by other JNI APIs to access fields and methods. Those other APIS presume that the class has been initialized without checking to help with performance.
When JNI was spec'ed, JVM/TI didn't exist and so the idea of another
API being able to return jfieldIDs or jmethodIDs was not considered.
So these JNI function families have a problem when called with
jfieldIDs or jmethodIDs that were obtained by JVM/TI instead of JNI:
Get<type>Field Routines
Set<type>Field Routines
GetStatic<type>Field Routines
SetStatic<type>Field Routines
Call*<type>Method* Routines
All of these JNI functions have an assumption that the associated
class has been initialized because the JNI functions that fetched
the jfieldIDs or jmethodIDs would have made sure of that. So when
we added JVM/TI, we probably should have added a JVM/TI specific
check to make sure that the associated class is initialized.
I don't know if the JNI functions will detect an error if one of
these functions is called on an uninitialized class. Because of
the age of the API, I suspect not. It should be possible to copy
a JVM/TI ClassPrepare event test and modify it to call a JNI
Get<type>Field() or GetStatic<type>Field() function and see what
happens.
The risk is exposing fields and methods of an uninitialized class to JNI.
This requires both a JVMTI specification and the related implementation change.
respectively arrays of jfieldIDs and jmethodIDs without triggering
class initialization.
These jfieldIDs and jmethodIDs are shared with JNI.
JNI GetFieldID and GetMethodID trigger class initialization prior to returning the jfieldIDs and jmethodIDs.
jfieldIDs and jmethodIDs can be used by other JNI APIs to access fields and methods. Those other APIS presume that the class has been initialized without checking to help with performance.
When JNI was spec'ed, JVM/TI didn't exist and so the idea of another
API being able to return jfieldIDs or jmethodIDs was not considered.
So these JNI function families have a problem when called with
jfieldIDs or jmethodIDs that were obtained by JVM/TI instead of JNI:
Get<type>Field Routines
Set<type>Field Routines
GetStatic<type>Field Routines
SetStatic<type>Field Routines
Call*<type>Method* Routines
All of these JNI functions have an assumption that the associated
class has been initialized because the JNI functions that fetched
the jfieldIDs or jmethodIDs would have made sure of that. So when
we added JVM/TI, we probably should have added a JVM/TI specific
check to make sure that the associated class is initialized.
I don't know if the JNI functions will detect an error if one of
these functions is called on an uninitialized class. Because of
the age of the API, I suspect not. It should be possible to copy
a JVM/TI ClassPrepare event test and modify it to call a JNI
Get<type>Field() or GetStatic<type>Field() function and see what
happens.
The risk is exposing fields and methods of an uninitialized class to JNI.
This requires both a JVMTI specification and the related implementation change.
- relates to
-
JDK-8181144 JDI - VirtualMachine.allClasses() does not return loaded but uninitialized class
-
- Closed
-