4917309: (cl) Reduce internal usage of ClassNotFoundExceptions during class-loading
Summary: Change findBootstrapClass to return null instead of throwing CNFE if class not found
Reviewed-by: alanb, dholmes, iris
--- a/jdk/src/share/classes/java/lang/ClassLoader.java Wed Aug 05 13:17:30 2009 -0600
+++ b/jdk/src/share/classes/java/lang/ClassLoader.java Thu Aug 06 11:25:12 2009 -0700
@@ -384,9 +384,14 @@
if (parent != null) {
c = parent.loadClass(name, false);
} else {
- c = findBootstrapClass0(name);
+ c = findBootstrapClassOrNull(name);
}
} 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
// to find the class.
c = findClass(name);
@@ -1008,22 +1013,29 @@
if (system == null) {
if (!checkName(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);
}
- 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();
- if (!checkName(name))
- throw new ClassNotFoundException(name);
+ if (!checkName(name)) return null;
+
return findBootstrapClass(name);
}
- private native Class findBootstrapClass(String name)
- throws ClassNotFoundException;
+ // return null if not found
+ private native Class findBootstrapClass(String name);
// Check to make sure the class loader has been initialized.
private void check() {
--- a/jdk/src/share/javavm/export/jvm.h Wed Aug 05 13:17:30 2009 -0600
+++ b/jdk/src/share/javavm/export/jvm.h Thu Aug 06 11:25:12 2009 -0700
@@ -375,6 +375,12 @@
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
* or NoClassDefFoundError depending on the value of the last
* argument.
--- a/jdk/src/share/native/java/lang/ClassLoader.c Wed Aug 05 13:17:30 2009 -0600
+++ b/jdk/src/share/native/java/lang/ClassLoader.c Thu Aug 06 11:25:12 2009 -0700
@@ -237,6 +237,9 @@
JVM_ResolveClass(env, cls);
}
+/*
+ * Returns NULL if class not found.
+ */
JNIEXPORT jclass JNICALL
Java_java_lang_ClassLoader_findBootstrapClass(JNIEnv *env, jobject loader,
jstring classname)
@@ -246,7 +249,6 @@
char buf[128];
if (classname == NULL) {
- JNU_ThrowClassNotFoundException(env, 0);
return 0;
}
@@ -258,11 +260,10 @@
VerifyFixClassname(clname);
if (!VerifyClassname(clname, JNI_TRUE)) { /* expects slashed name */
- JNU_ThrowClassNotFoundException(env, clname);
goto done;
}
- cls = JVM_FindClassFromClassLoader(env, clname, JNI_FALSE, 0, JNI_FALSE);
+ cls = JVM_FindClassFromBootLoader(env, clname);
done:
if (clname != buf) {