6755845: JVM_FindClassFromBoot triggers assertions
Fixes assertions caused by one jvm_entry calling another, solved by refactoring code and modified gamma test. Reviewed-by: dholmes, xlu
This commit is contained in:
parent
fe28b4f768
commit
3a72f5c241
@ -1110,7 +1110,7 @@ static jstring getPlatformEncoding(JNIEnv *env) {
|
||||
if (propname) {
|
||||
jclass cls;
|
||||
jmethodID mid;
|
||||
NULL_CHECK0 (cls = (*env)->FindClass(env, "java/lang/System"));
|
||||
NULL_CHECK0 (cls = FindBootStrapClass(env, "java/lang/System"));
|
||||
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
|
||||
env, cls,
|
||||
"getProperty",
|
||||
@ -1125,7 +1125,7 @@ static jstring getPlatformEncoding(JNIEnv *env) {
|
||||
static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
|
||||
jclass cls;
|
||||
jmethodID mid;
|
||||
NULL_CHECK0 (cls = (*env)->FindClass(env, "java/nio/charset/Charset"));
|
||||
NULL_CHECK0 (cls = FindBootStrapClass(env, "java/nio/charset/Charset"));
|
||||
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
|
||||
env, cls,
|
||||
"isSupported",
|
||||
@ -1161,7 +1161,7 @@ NewPlatformString(JNIEnv *env, char *s)
|
||||
#else
|
||||
if (isEncodingSupported(env, enc) == JNI_TRUE) {
|
||||
#endif
|
||||
NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
|
||||
NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
|
||||
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
|
||||
"([BLjava/lang/String;)V"));
|
||||
str = (*env)->NewObject(env, cls, mid, ary, enc);
|
||||
@ -1172,7 +1172,7 @@ NewPlatformString(JNIEnv *env, char *s)
|
||||
the encoding name, in which the StringCoding class will
|
||||
pickup the iso-8859-1 as the fallback converter for us.
|
||||
*/
|
||||
NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
|
||||
NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
|
||||
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
|
||||
"([B)V"));
|
||||
str = (*env)->NewObject(env, cls, mid, ary);
|
||||
@ -1195,7 +1195,7 @@ NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
|
||||
jarray ary;
|
||||
int i;
|
||||
|
||||
NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
|
||||
NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
|
||||
NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0));
|
||||
for (i = 0; i < strc; i++) {
|
||||
jstring str = NewPlatformString(env, *strv++);
|
||||
@ -1224,6 +1224,7 @@ LoadClass(JNIEnv *env, char *name)
|
||||
c = *t++;
|
||||
*s++ = (c == '.') ? '/' : c;
|
||||
} while (c != '\0');
|
||||
// use the application class loader for main-class
|
||||
cls = (*env)->FindClass(env, buf);
|
||||
free(buf);
|
||||
|
||||
@ -1250,7 +1251,7 @@ GetMainClassName(JNIEnv *env, char *jarname)
|
||||
jobject jar, man, attr;
|
||||
jstring str, result = 0;
|
||||
|
||||
NULL_CHECK0(cls = (*env)->FindClass(env, "java/util/jar/JarFile"));
|
||||
NULL_CHECK0(cls = FindBootStrapClass(env, "java/util/jar/JarFile"));
|
||||
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
|
||||
"(Ljava/lang/String;)V"));
|
||||
NULL_CHECK0(str = NewPlatformString(env, jarname));
|
||||
@ -1471,7 +1472,7 @@ PrintJavaVersion(JNIEnv *env)
|
||||
jclass ver;
|
||||
jmethodID print;
|
||||
|
||||
NULL_CHECK(ver = (*env)->FindClass(env, "sun/misc/Version"));
|
||||
NULL_CHECK(ver = FindBootStrapClass(env, "sun/misc/Version"));
|
||||
NULL_CHECK(print = (*env)->GetStaticMethodID(env, ver, "print", "()V"));
|
||||
|
||||
(*env)->CallStaticVoidMethod(env, ver, print);
|
||||
|
@ -100,5 +100,15 @@ void* MemAlloc(size_t size);
|
||||
* Make launcher spit debug output.
|
||||
*/
|
||||
extern jboolean _launcher_debug;
|
||||
/*
|
||||
* This allows for finding classes from the VM's bootstrap class loader
|
||||
* directly, FindClass uses the application class loader internally, this will
|
||||
* cause unnecessary searching of the classpath for the required classes.
|
||||
*/
|
||||
typedef jclass (JNICALL FindClassFromBootLoader_t(JNIEnv *env,
|
||||
const char *name,
|
||||
jboolean throwError));
|
||||
|
||||
jclass FindBootStrapClass(JNIEnv *env, const char *classname);
|
||||
|
||||
#endif /* _JAVA_H_ */
|
||||
|
@ -1826,3 +1826,23 @@ UnsetEnv(char *name)
|
||||
{
|
||||
return(borrowed_unsetenv(name));
|
||||
}
|
||||
/*
|
||||
* The implementation for finding classes from the bootstrap
|
||||
* class loader, refer to java.h
|
||||
*/
|
||||
static FindClassFromBootLoader_t *findBootClass = NULL;
|
||||
|
||||
jclass
|
||||
FindBootStrapClass(JNIEnv *env, const char* classname)
|
||||
{
|
||||
if (findBootClass == NULL) {
|
||||
findBootClass = (FindClassFromBootLoader_t *)dlsym(RTLD_DEFAULT,
|
||||
"JVM_FindClassFromBootLoader");
|
||||
if (findBootClass == NULL) {
|
||||
fprintf(stderr, "Error: could load method JVM_FindClassFromBootLoader");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return findBootClass(env, classname, JNI_FALSE);
|
||||
}
|
||||
|
||||
|
@ -1110,7 +1110,7 @@ static jstring getPlatformEncoding(JNIEnv *env) {
|
||||
if (propname) {
|
||||
jclass cls;
|
||||
jmethodID mid;
|
||||
NULL_CHECK0 (cls = (*env)->FindClass(env, "java/lang/System"));
|
||||
NULL_CHECK0 (cls = FindBootStrapClass(env, "java/lang/System"));
|
||||
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
|
||||
env, cls,
|
||||
"getProperty",
|
||||
@ -1125,7 +1125,7 @@ static jstring getPlatformEncoding(JNIEnv *env) {
|
||||
static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
|
||||
jclass cls;
|
||||
jmethodID mid;
|
||||
NULL_CHECK0 (cls = (*env)->FindClass(env, "java/nio/charset/Charset"));
|
||||
NULL_CHECK0 (cls = FindBootStrapClass(env, "java/nio/charset/Charset"));
|
||||
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
|
||||
env, cls,
|
||||
"isSupported",
|
||||
@ -1161,7 +1161,7 @@ NewPlatformString(JNIEnv *env, char *s)
|
||||
#else
|
||||
if (isEncodingSupported(env, enc) == JNI_TRUE) {
|
||||
#endif
|
||||
NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
|
||||
NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
|
||||
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
|
||||
"([BLjava/lang/String;)V"));
|
||||
str = (*env)->NewObject(env, cls, mid, ary, enc);
|
||||
@ -1172,7 +1172,7 @@ NewPlatformString(JNIEnv *env, char *s)
|
||||
the encoding name, in which the StringCoding class will
|
||||
pickup the iso-8859-1 as the fallback converter for us.
|
||||
*/
|
||||
NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
|
||||
NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
|
||||
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
|
||||
"([B)V"));
|
||||
str = (*env)->NewObject(env, cls, mid, ary);
|
||||
@ -1195,7 +1195,7 @@ NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
|
||||
jarray ary;
|
||||
int i;
|
||||
|
||||
NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
|
||||
NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
|
||||
NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0));
|
||||
for (i = 0; i < strc; i++) {
|
||||
jstring str = NewPlatformString(env, *strv++);
|
||||
@ -1224,6 +1224,7 @@ LoadClass(JNIEnv *env, char *name)
|
||||
c = *t++;
|
||||
*s++ = (c == '.') ? '/' : c;
|
||||
} while (c != '\0');
|
||||
// use the application class loader for the main-class
|
||||
cls = (*env)->FindClass(env, buf);
|
||||
free(buf);
|
||||
|
||||
@ -1250,7 +1251,7 @@ GetMainClassName(JNIEnv *env, char *jarname)
|
||||
jobject jar, man, attr;
|
||||
jstring str, result = 0;
|
||||
|
||||
NULL_CHECK0(cls = (*env)->FindClass(env, "java/util/jar/JarFile"));
|
||||
NULL_CHECK0(cls = FindBootStrapClass(env, "java/util/jar/JarFile"));
|
||||
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
|
||||
"(Ljava/lang/String;)V"));
|
||||
NULL_CHECK0(str = NewPlatformString(env, jarname));
|
||||
@ -1471,7 +1472,7 @@ PrintJavaVersion(JNIEnv *env)
|
||||
jclass ver;
|
||||
jmethodID print;
|
||||
|
||||
NULL_CHECK(ver = (*env)->FindClass(env, "sun/misc/Version"));
|
||||
NULL_CHECK(ver = FindBootStrapClass(env, "sun/misc/Version"));
|
||||
NULL_CHECK(print = (*env)->GetStaticMethodID(env, ver, "print", "()V"));
|
||||
|
||||
(*env)->CallStaticVoidMethod(env, ver, print);
|
||||
|
@ -101,4 +101,15 @@ void* MemAlloc(size_t size);
|
||||
*/
|
||||
extern jboolean _launcher_debug;
|
||||
|
||||
/*
|
||||
* This allows for finding classes from the VM's bootstrap class loader
|
||||
* directly, FindClass uses the application class loader internally, this will
|
||||
* cause unnecessary searching of the classpath for the required classes.
|
||||
*/
|
||||
typedef jclass (JNICALL FindClassFromBootLoader_t(JNIEnv *env,
|
||||
const char *name,
|
||||
jboolean throwError));
|
||||
|
||||
jclass FindBootStrapClass(JNIEnv *env, const char *classname);
|
||||
|
||||
#endif /* _JAVA_H_ */
|
||||
|
@ -1826,3 +1826,24 @@ UnsetEnv(char *name)
|
||||
{
|
||||
return(borrowed_unsetenv(name));
|
||||
}
|
||||
|
||||
/*
|
||||
* The implementation for finding classes from the bootstrap
|
||||
* class loader, refer to java.h
|
||||
*/
|
||||
static FindClassFromBootLoader_t *findBootClass = NULL;
|
||||
|
||||
jclass
|
||||
FindBootStrapClass(JNIEnv *env, const char* classname)
|
||||
{
|
||||
if (findBootClass == NULL) {
|
||||
findBootClass = (FindClassFromBootLoader_t *)dlsym(RTLD_DEFAULT,
|
||||
"JVM_FindClassFromBootLoader");
|
||||
if (findBootClass == NULL) {
|
||||
fprintf(stderr, "Error: could not load method JVM_FindClassFromBootLoader");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return findBootClass(env, classname, JNI_FALSE);
|
||||
}
|
||||
|
||||
|
@ -628,6 +628,32 @@ JVM_ENTRY(void, JVM_ResolveClass(JNIEnv* env, jclass cls))
|
||||
if (PrintJVMWarnings) warning("JVM_ResolveClass not implemented");
|
||||
JVM_END
|
||||
|
||||
// Common implementation for JVM_FindClassFromBootLoader and
|
||||
// JVM_FindClassFromLoader
|
||||
static jclass jvm_find_class_from_class_loader(JNIEnv* env, const char* name,
|
||||
jboolean init, jobject loader,
|
||||
jboolean throwError, TRAPS) {
|
||||
// Java libraries should ensure that name is never null...
|
||||
if (name == NULL || (int)strlen(name) > symbolOopDesc::max_length()) {
|
||||
// It's impossible to create this class; the name cannot fit
|
||||
// into the constant pool.
|
||||
if (throwError) {
|
||||
THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);
|
||||
} else {
|
||||
THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), name);
|
||||
}
|
||||
}
|
||||
symbolHandle h_name = oopFactory::new_symbol_handle(name, CHECK_NULL);
|
||||
Handle h_loader(THREAD, JNIHandles::resolve(loader));
|
||||
jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
|
||||
Handle(), throwError, THREAD);
|
||||
|
||||
if (TraceClassResolution && result != NULL) {
|
||||
trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Rationale behind JVM_FindClassFromBootLoader
|
||||
// a> JVM_FindClassFromClassLoader was never exported in the export tables.
|
||||
// b> because of (a) java.dll has a direct dependecy on the unexported
|
||||
@ -649,8 +675,8 @@ JVM_ENTRY(jclass, JVM_FindClassFromBootLoader(JNIEnv* env,
|
||||
jboolean throwError))
|
||||
JVMWrapper3("JVM_FindClassFromBootLoader %s throw %s", name,
|
||||
throwError ? "error" : "exception");
|
||||
return JVM_FindClassFromClassLoader(env, name, JNI_FALSE,
|
||||
(jobject)NULL, throwError);
|
||||
return jvm_find_class_from_class_loader(env, name, JNI_FALSE,
|
||||
(jobject)NULL, throwError, THREAD);
|
||||
JVM_END
|
||||
|
||||
JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name,
|
||||
@ -658,26 +684,8 @@ JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name,
|
||||
jboolean throwError))
|
||||
JVMWrapper3("JVM_FindClassFromClassLoader %s throw %s", name,
|
||||
throwError ? "error" : "exception");
|
||||
// Java libraries should ensure that name is never null...
|
||||
if (name == NULL || (int)strlen(name) > symbolOopDesc::max_length()) {
|
||||
// It's impossible to create this class; the name cannot fit
|
||||
// into the constant pool.
|
||||
if (throwError) {
|
||||
THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);
|
||||
} else {
|
||||
THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), name);
|
||||
}
|
||||
}
|
||||
symbolHandle h_name = oopFactory::new_symbol_handle(name, CHECK_NULL);
|
||||
Handle h_loader(THREAD, JNIHandles::resolve(loader));
|
||||
jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
|
||||
Handle(), throwError, thread);
|
||||
|
||||
if (TraceClassResolution && result != NULL) {
|
||||
trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result)));
|
||||
}
|
||||
|
||||
return result;
|
||||
return jvm_find_class_from_class_loader(env, name, init, loader,
|
||||
throwError, THREAD);
|
||||
JVM_END
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user