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) {
|
if (propname) {
|
||||||
jclass cls;
|
jclass cls;
|
||||||
jmethodID mid;
|
jmethodID mid;
|
||||||
NULL_CHECK0 (cls = (*env)->FindClass(env, "java/lang/System"));
|
NULL_CHECK0 (cls = FindBootStrapClass(env, "java/lang/System"));
|
||||||
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
|
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
|
||||||
env, cls,
|
env, cls,
|
||||||
"getProperty",
|
"getProperty",
|
||||||
@ -1125,7 +1125,7 @@ static jstring getPlatformEncoding(JNIEnv *env) {
|
|||||||
static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
|
static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
|
||||||
jclass cls;
|
jclass cls;
|
||||||
jmethodID mid;
|
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(
|
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
|
||||||
env, cls,
|
env, cls,
|
||||||
"isSupported",
|
"isSupported",
|
||||||
@ -1161,7 +1161,7 @@ NewPlatformString(JNIEnv *env, char *s)
|
|||||||
#else
|
#else
|
||||||
if (isEncodingSupported(env, enc) == JNI_TRUE) {
|
if (isEncodingSupported(env, enc) == JNI_TRUE) {
|
||||||
#endif
|
#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>",
|
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
|
||||||
"([BLjava/lang/String;)V"));
|
"([BLjava/lang/String;)V"));
|
||||||
str = (*env)->NewObject(env, cls, mid, ary, enc);
|
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
|
the encoding name, in which the StringCoding class will
|
||||||
pickup the iso-8859-1 as the fallback converter for us.
|
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>",
|
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
|
||||||
"([B)V"));
|
"([B)V"));
|
||||||
str = (*env)->NewObject(env, cls, mid, ary);
|
str = (*env)->NewObject(env, cls, mid, ary);
|
||||||
@ -1195,7 +1195,7 @@ NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
|
|||||||
jarray ary;
|
jarray ary;
|
||||||
int i;
|
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));
|
NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0));
|
||||||
for (i = 0; i < strc; i++) {
|
for (i = 0; i < strc; i++) {
|
||||||
jstring str = NewPlatformString(env, *strv++);
|
jstring str = NewPlatformString(env, *strv++);
|
||||||
@ -1224,6 +1224,7 @@ LoadClass(JNIEnv *env, char *name)
|
|||||||
c = *t++;
|
c = *t++;
|
||||||
*s++ = (c == '.') ? '/' : c;
|
*s++ = (c == '.') ? '/' : c;
|
||||||
} while (c != '\0');
|
} while (c != '\0');
|
||||||
|
// use the application class loader for main-class
|
||||||
cls = (*env)->FindClass(env, buf);
|
cls = (*env)->FindClass(env, buf);
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
||||||
@ -1250,7 +1251,7 @@ GetMainClassName(JNIEnv *env, char *jarname)
|
|||||||
jobject jar, man, attr;
|
jobject jar, man, attr;
|
||||||
jstring str, result = 0;
|
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>",
|
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
|
||||||
"(Ljava/lang/String;)V"));
|
"(Ljava/lang/String;)V"));
|
||||||
NULL_CHECK0(str = NewPlatformString(env, jarname));
|
NULL_CHECK0(str = NewPlatformString(env, jarname));
|
||||||
@ -1471,7 +1472,7 @@ PrintJavaVersion(JNIEnv *env)
|
|||||||
jclass ver;
|
jclass ver;
|
||||||
jmethodID print;
|
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"));
|
NULL_CHECK(print = (*env)->GetStaticMethodID(env, ver, "print", "()V"));
|
||||||
|
|
||||||
(*env)->CallStaticVoidMethod(env, ver, print);
|
(*env)->CallStaticVoidMethod(env, ver, print);
|
||||||
|
@ -100,5 +100,15 @@ void* MemAlloc(size_t size);
|
|||||||
* Make launcher spit debug output.
|
* Make launcher spit debug output.
|
||||||
*/
|
*/
|
||||||
extern jboolean _launcher_debug;
|
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_ */
|
#endif /* _JAVA_H_ */
|
||||||
|
@ -1826,3 +1826,23 @@ UnsetEnv(char *name)
|
|||||||
{
|
{
|
||||||
return(borrowed_unsetenv(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) {
|
if (propname) {
|
||||||
jclass cls;
|
jclass cls;
|
||||||
jmethodID mid;
|
jmethodID mid;
|
||||||
NULL_CHECK0 (cls = (*env)->FindClass(env, "java/lang/System"));
|
NULL_CHECK0 (cls = FindBootStrapClass(env, "java/lang/System"));
|
||||||
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
|
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
|
||||||
env, cls,
|
env, cls,
|
||||||
"getProperty",
|
"getProperty",
|
||||||
@ -1125,7 +1125,7 @@ static jstring getPlatformEncoding(JNIEnv *env) {
|
|||||||
static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
|
static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
|
||||||
jclass cls;
|
jclass cls;
|
||||||
jmethodID mid;
|
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(
|
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
|
||||||
env, cls,
|
env, cls,
|
||||||
"isSupported",
|
"isSupported",
|
||||||
@ -1161,7 +1161,7 @@ NewPlatformString(JNIEnv *env, char *s)
|
|||||||
#else
|
#else
|
||||||
if (isEncodingSupported(env, enc) == JNI_TRUE) {
|
if (isEncodingSupported(env, enc) == JNI_TRUE) {
|
||||||
#endif
|
#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>",
|
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
|
||||||
"([BLjava/lang/String;)V"));
|
"([BLjava/lang/String;)V"));
|
||||||
str = (*env)->NewObject(env, cls, mid, ary, enc);
|
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
|
the encoding name, in which the StringCoding class will
|
||||||
pickup the iso-8859-1 as the fallback converter for us.
|
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>",
|
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
|
||||||
"([B)V"));
|
"([B)V"));
|
||||||
str = (*env)->NewObject(env, cls, mid, ary);
|
str = (*env)->NewObject(env, cls, mid, ary);
|
||||||
@ -1195,7 +1195,7 @@ NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
|
|||||||
jarray ary;
|
jarray ary;
|
||||||
int i;
|
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));
|
NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0));
|
||||||
for (i = 0; i < strc; i++) {
|
for (i = 0; i < strc; i++) {
|
||||||
jstring str = NewPlatformString(env, *strv++);
|
jstring str = NewPlatformString(env, *strv++);
|
||||||
@ -1224,6 +1224,7 @@ LoadClass(JNIEnv *env, char *name)
|
|||||||
c = *t++;
|
c = *t++;
|
||||||
*s++ = (c == '.') ? '/' : c;
|
*s++ = (c == '.') ? '/' : c;
|
||||||
} while (c != '\0');
|
} while (c != '\0');
|
||||||
|
// use the application class loader for the main-class
|
||||||
cls = (*env)->FindClass(env, buf);
|
cls = (*env)->FindClass(env, buf);
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
||||||
@ -1250,7 +1251,7 @@ GetMainClassName(JNIEnv *env, char *jarname)
|
|||||||
jobject jar, man, attr;
|
jobject jar, man, attr;
|
||||||
jstring str, result = 0;
|
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>",
|
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
|
||||||
"(Ljava/lang/String;)V"));
|
"(Ljava/lang/String;)V"));
|
||||||
NULL_CHECK0(str = NewPlatformString(env, jarname));
|
NULL_CHECK0(str = NewPlatformString(env, jarname));
|
||||||
@ -1471,7 +1472,7 @@ PrintJavaVersion(JNIEnv *env)
|
|||||||
jclass ver;
|
jclass ver;
|
||||||
jmethodID print;
|
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"));
|
NULL_CHECK(print = (*env)->GetStaticMethodID(env, ver, "print", "()V"));
|
||||||
|
|
||||||
(*env)->CallStaticVoidMethod(env, ver, print);
|
(*env)->CallStaticVoidMethod(env, ver, print);
|
||||||
|
@ -101,4 +101,15 @@ void* MemAlloc(size_t size);
|
|||||||
*/
|
*/
|
||||||
extern jboolean _launcher_debug;
|
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_ */
|
#endif /* _JAVA_H_ */
|
||||||
|
@ -1826,3 +1826,24 @@ UnsetEnv(char *name)
|
|||||||
{
|
{
|
||||||
return(borrowed_unsetenv(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");
|
if (PrintJVMWarnings) warning("JVM_ResolveClass not implemented");
|
||||||
JVM_END
|
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
|
// Rationale behind JVM_FindClassFromBootLoader
|
||||||
// a> JVM_FindClassFromClassLoader was never exported in the export tables.
|
// a> JVM_FindClassFromClassLoader was never exported in the export tables.
|
||||||
// b> because of (a) java.dll has a direct dependecy on the unexported
|
// 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))
|
jboolean throwError))
|
||||||
JVMWrapper3("JVM_FindClassFromBootLoader %s throw %s", name,
|
JVMWrapper3("JVM_FindClassFromBootLoader %s throw %s", name,
|
||||||
throwError ? "error" : "exception");
|
throwError ? "error" : "exception");
|
||||||
return JVM_FindClassFromClassLoader(env, name, JNI_FALSE,
|
return jvm_find_class_from_class_loader(env, name, JNI_FALSE,
|
||||||
(jobject)NULL, throwError);
|
(jobject)NULL, throwError, THREAD);
|
||||||
JVM_END
|
JVM_END
|
||||||
|
|
||||||
JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name,
|
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))
|
jboolean throwError))
|
||||||
JVMWrapper3("JVM_FindClassFromClassLoader %s throw %s", name,
|
JVMWrapper3("JVM_FindClassFromClassLoader %s throw %s", name,
|
||||||
throwError ? "error" : "exception");
|
throwError ? "error" : "exception");
|
||||||
// Java libraries should ensure that name is never null...
|
return jvm_find_class_from_class_loader(env, name, init, loader,
|
||||||
if (name == NULL || (int)strlen(name) > symbolOopDesc::max_length()) {
|
throwError, THREAD);
|
||||||
// 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;
|
|
||||||
JVM_END
|
JVM_END
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user