8188052: JNI FindClass needs to specify the class loading context used for library lifecycle hooks
Reviewed-by: alanb, coleenp, dholmes
This commit is contained in:
parent
42a29333b9
commit
4c1297b778
@ -92,7 +92,7 @@
|
||||
#include "jvmci/jvmciRuntime.hpp"
|
||||
#endif
|
||||
|
||||
static jint CurrentVersion = JNI_VERSION_9;
|
||||
static jint CurrentVersion = JNI_VERSION_10;
|
||||
|
||||
#ifdef _WIN32
|
||||
extern LONG WINAPI topLevelExceptionFilter(_EXCEPTION_POINTERS* );
|
||||
@ -401,29 +401,31 @@ JNI_ENTRY(jclass, jni_FindClass(JNIEnv *env, const char *name))
|
||||
// Find calling class
|
||||
Klass* k = thread->security_get_caller_class(0);
|
||||
if (k != NULL) {
|
||||
loader = Handle(THREAD, k->class_loader());
|
||||
// Special handling to make sure JNI_OnLoad and JNI_OnUnload are executed
|
||||
// in the correct class context.
|
||||
if (loader.is_null() &&
|
||||
if (k->class_loader() == NULL &&
|
||||
k->name() == vmSymbols::java_lang_ClassLoader_NativeLibrary()) {
|
||||
JavaValue result(T_OBJECT);
|
||||
JavaCalls::call_static(&result, k,
|
||||
vmSymbols::getFromClass_name(),
|
||||
vmSymbols::void_class_signature(),
|
||||
thread);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
Handle ex(thread, thread->pending_exception());
|
||||
CLEAR_PENDING_EXCEPTION;
|
||||
THROW_HANDLE_0(ex);
|
||||
}
|
||||
CHECK_NULL);
|
||||
// When invoked from JNI_OnLoad, NativeLibrary::getFromClass returns
|
||||
// a non-NULL Class object. When invoked from JNI_OnUnload,
|
||||
// it will return NULL to indicate no context.
|
||||
oop mirror = (oop) result.get_jobject();
|
||||
loader = Handle(THREAD,
|
||||
InstanceKlass::cast(java_lang_Class::as_Klass(mirror))->class_loader());
|
||||
protection_domain = Handle(THREAD,
|
||||
InstanceKlass::cast(java_lang_Class::as_Klass(mirror))->protection_domain());
|
||||
if (mirror != NULL) {
|
||||
Klass* fromClass = java_lang_Class::as_Klass(mirror);
|
||||
loader = Handle(THREAD, fromClass->class_loader());
|
||||
protection_domain = Handle(THREAD, fromClass->protection_domain());
|
||||
}
|
||||
} else {
|
||||
loader = Handle(THREAD, k->class_loader());
|
||||
}
|
||||
} else {
|
||||
// We call ClassLoader.getSystemClassLoader to obtain the system class loader.
|
||||
}
|
||||
|
||||
if (loader.is_null()) {
|
||||
// No context and use the system class loader
|
||||
loader = Handle(THREAD, SystemDictionary::java_system_loader());
|
||||
}
|
||||
|
||||
|
@ -1964,6 +1964,7 @@ JNI_OnUnload(JavaVM *vm, void *reserved);
|
||||
#define JNI_VERSION_1_6 0x00010006
|
||||
#define JNI_VERSION_1_8 0x00010008
|
||||
#define JNI_VERSION_9 0x00090000
|
||||
#define JNI_VERSION_10 0x000a0000
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -4195,6 +4195,7 @@ jboolean Threads::is_supported_jni_version(jint version) {
|
||||
if (version == JNI_VERSION_1_6) return JNI_TRUE;
|
||||
if (version == JNI_VERSION_1_8) return JNI_TRUE;
|
||||
if (version == JNI_VERSION_9) return JNI_TRUE;
|
||||
if (version == JNI_VERSION_10) return JNI_TRUE;
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
|
@ -2381,7 +2381,7 @@ public abstract class ClassLoader {
|
||||
private int jniVersion;
|
||||
// the class from which the library is loaded, also indicates
|
||||
// the loader this native library belongs.
|
||||
private final Class<?> fromClass;
|
||||
private Class<?> fromClass;
|
||||
// the canonicalized name of the native library.
|
||||
// or static library name
|
||||
String name;
|
||||
@ -2404,6 +2404,8 @@ public abstract class ClassLoader {
|
||||
protected void finalize() {
|
||||
synchronized (loadedLibraryNames) {
|
||||
if (fromClass.getClassLoader() != null && loaded) {
|
||||
this.fromClass = null; // no context when unloaded
|
||||
|
||||
/* remove the native library name */
|
||||
int size = loadedLibraryNames.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
|
@ -1964,6 +1964,7 @@ JNI_OnUnload(JavaVM *vm, void *reserved);
|
||||
#define JNI_VERSION_1_6 0x00010006
|
||||
#define JNI_VERSION_1_8 0x00010008
|
||||
#define JNI_VERSION_9 0x00090000
|
||||
#define JNI_VERSION_10 0x000a0000
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -45,7 +45,7 @@ JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||
return JNI_EVERSION; /* JNI version not supported */
|
||||
}
|
||||
|
||||
return JNI_VERSION_9;
|
||||
return JNI_VERSION_10;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -39,7 +39,7 @@ JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||
return JNI_EVERSION; /* JNI version not supported */
|
||||
}
|
||||
|
||||
return JNI_VERSION_9;
|
||||
return JNI_VERSION_10;
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,12 +27,12 @@
|
||||
*/
|
||||
public class JniVersion {
|
||||
|
||||
public static final int JNI_VERSION_9 = 0x00090000;
|
||||
public static final int JNI_VERSION_10 = 0x000a0000;
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
System.loadLibrary("JniVersion");
|
||||
int res = getJniVersion();
|
||||
if (res != JNI_VERSION_9) {
|
||||
if (res != JNI_VERSION_10) {
|
||||
throw new Exception("Unexpected value returned from getJniVersion(): 0x" + Integer.toHexString(res));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user