4917309: (cl) Reduce internal usage of ClassNotFoundExceptions during class-loading

Change findBootstrapClass to return null instead of throwing CNFE if class not found

Reviewed-by: alanb, dholmes, iris
This commit is contained in:
Mandy Chung 2009-08-06 11:25:12 -07:00
parent 8790c489e1
commit 0f923041b9
3 changed files with 30 additions and 11 deletions

View File

@ -384,9 +384,14 @@ public abstract class ClassLoader {
if (parent != null) { if (parent != null) {
c = parent.loadClass(name, false); c = parent.loadClass(name, false);
} else { } else {
c = findBootstrapClass0(name); c = findBootstrapClassOrNull(name);
} }
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
// If still not found, then invoke findClass in order // If still not found, then invoke findClass in order
// to find the class. // to find the class.
c = findClass(name); c = findClass(name);
@ -1008,22 +1013,29 @@ public abstract class ClassLoader {
if (system == null) { if (system == null) {
if (!checkName(name)) if (!checkName(name))
throw new ClassNotFoundException(name); throw new ClassNotFoundException(name);
return findBootstrapClass(name); Class cls = findBootstrapClass(name);
if (cls == null) {
throw new ClassNotFoundException(name);
}
return cls;
} }
return system.loadClass(name); return system.loadClass(name);
} }
private Class findBootstrapClass0(String name) /**
throws ClassNotFoundException * Returns a class loaded by the bootstrap class loader;
* or return null if not found.
*/
private Class findBootstrapClassOrNull(String name)
{ {
check(); check();
if (!checkName(name)) if (!checkName(name)) return null;
throw new ClassNotFoundException(name);
return findBootstrapClass(name); return findBootstrapClass(name);
} }
private native Class findBootstrapClass(String name) // return null if not found
throws ClassNotFoundException; private native Class findBootstrapClass(String name);
// Check to make sure the class loader has been initialized. // Check to make sure the class loader has been initialized.
private void check() { private void check() {

View File

@ -374,6 +374,12 @@ JVM_FindPrimitiveClass(JNIEnv *env, const char *utf);
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
JVM_ResolveClass(JNIEnv *env, jclass cls); JVM_ResolveClass(JNIEnv *env, jclass cls);
/*
* Find a class from a boot class loader. Returns NULL if class not found.
*/
JNIEXPORT jclass JNICALL
JVM_FindClassFromBootLoader(JNIEnv *env, const char *name);
/* /*
* Find a class from a given class loader. Throw ClassNotFoundException * Find a class from a given class loader. Throw ClassNotFoundException
* or NoClassDefFoundError depending on the value of the last * or NoClassDefFoundError depending on the value of the last

View File

@ -237,6 +237,9 @@ Java_java_lang_ClassLoader_resolveClass0(JNIEnv *env, jobject this,
JVM_ResolveClass(env, cls); JVM_ResolveClass(env, cls);
} }
/*
* Returns NULL if class not found.
*/
JNIEXPORT jclass JNICALL JNIEXPORT jclass JNICALL
Java_java_lang_ClassLoader_findBootstrapClass(JNIEnv *env, jobject loader, Java_java_lang_ClassLoader_findBootstrapClass(JNIEnv *env, jobject loader,
jstring classname) jstring classname)
@ -246,7 +249,6 @@ Java_java_lang_ClassLoader_findBootstrapClass(JNIEnv *env, jobject loader,
char buf[128]; char buf[128];
if (classname == NULL) { if (classname == NULL) {
JNU_ThrowClassNotFoundException(env, 0);
return 0; return 0;
} }
@ -258,11 +260,10 @@ Java_java_lang_ClassLoader_findBootstrapClass(JNIEnv *env, jobject loader,
VerifyFixClassname(clname); VerifyFixClassname(clname);
if (!VerifyClassname(clname, JNI_TRUE)) { /* expects slashed name */ if (!VerifyClassname(clname, JNI_TRUE)) { /* expects slashed name */
JNU_ThrowClassNotFoundException(env, clname);
goto done; goto done;
} }
cls = JVM_FindClassFromClassLoader(env, clname, JNI_FALSE, 0, JNI_FALSE); cls = JVM_FindClassFromBootLoader(env, clname);
done: done:
if (clname != buf) { if (clname != buf) {