Eliminating calls to Thread.getContextClassLoader().

From my mail to Norris Boyd:

When considering http://bugzilla.mozilla.org/show_bug.cgi?id=166530 I realized that my 2 years old suggestion to use Thread.getContextClassLoader() in org.mozilla.classfile.DefiningClassLoader was wrong, as it does not follow class loader chain pattern Rhino embeddings can use. Moreover, it is wrong to use Thread.getContextClassLoader() when searching for Rhino classes as if Rhino is available via the system class loader and an application uses its copy from another loader, Thread.getContextClassLoader() would return incompatible class while simple Class.forName() would do proper job of loading the requested class from a loader of Class.forName() caller.

The only place where Thread.getContextClassLoader() can be useful is when searching for classes in NativeJavaPackage, but even there with a new option to use Package with an explicit class loader argument it is not necessary as one can write in a script
Packages(java.lang.Thread.contextClassLoader) to get necessary behavior.
This commit is contained in:
igor%mir2.org 2002-12-30 18:22:58 +00:00
Родитель 79a67aa80c
Коммит 0499c96033
4 изменённых файлов: 22 добавлений и 72 удалений

Просмотреть файл

@ -50,20 +50,8 @@ import org.mozilla.javascript.GeneratedClassLoader;
public class DefiningClassLoader extends ClassLoader
implements GeneratedClassLoader
{
public static ClassLoader getContextClassLoader() {
try {
if (getContextClassLoaderMethod != null) {
return (ClassLoader) getContextClassLoaderMethod.invoke(
Thread.currentThread(),
new Object[0]);
}
} catch (IllegalAccessException e) {
// fall through...
} catch (InvocationTargetException e) {
// fall through...
}
return DefiningClassLoader.class.getClassLoader();
public DefiningClassLoader() {
this.parentLoader = getClass().getClassLoader();
}
public Class defineClass(String name, byte[] data) {
@ -79,9 +67,8 @@ public class DefiningClassLoader extends ClassLoader
{
Class clazz = findLoadedClass(name);
if (clazz == null) {
ClassLoader loader = getContextClassLoader();
if (loader != null) {
clazz = loader.loadClass(name);
if (parentLoader != null) {
clazz = parentLoader.loadClass(name);
} else {
clazz = findSystemClass(name);
}
@ -91,25 +78,5 @@ public class DefiningClassLoader extends ClassLoader
return clazz;
}
private static Method getContextClassLoaderMethod;
static {
try {
// Don't use "Thread.class": that performs the lookup
// in the class initializer, which doesn't allow us to
// catch possible security exceptions.
Class threadClass = Class.forName("java.lang.Thread");
// We'd like to use "getContextClassLoader", but
// that's only available on Java2.
getContextClassLoaderMethod =
threadClass.getDeclaredMethod("getContextClassLoader",
new Class[0]);
} catch (ClassNotFoundException e) {
// ignore exceptions; we'll use Class.forName instead.
} catch (NoSuchMethodException e) {
// ignore exceptions; we'll use Class.forName instead.
} catch (SecurityException e) {
// ignore exceptions; we'll use Class.forName instead.
}
}
private ClassLoader parentLoader;
}

Просмотреть файл

@ -688,7 +688,7 @@ public class FunctionObject extends BaseFunction {
/** Get default master implementation or null if not available */
private static Invoker newInvokerMaster() {
try {
Class cl = ScriptRuntime.loadClassName(INVOKER_MASTER_CLASS);
Class cl = Class.forName(INVOKER_MASTER_CLASS);
return (Invoker)cl.newInstance();
}
catch (ClassNotFoundException ex) {}

Просмотреть файл

@ -38,6 +38,7 @@
package org.mozilla.javascript;
import java.lang.reflect.*;
import org.mozilla.classfile.DefiningClassLoader;
/**
* This class reflects Java packages into the JavaScript environment. We
@ -207,7 +208,7 @@ public class NativeJavaPackage extends ScriptableObject {
String newPackage = packageName.length() == 0
? name
: packageName + "." + name;
: packageName + '.' + name;
Context cx = Context.getContext();
ClassShutter shutter = cx.getClassShutter();
Scriptable newValue = null;
@ -273,16 +274,17 @@ public class NativeJavaPackage extends ScriptableObject {
}
private static Class findClass(ClassLoader loader, String className) {
try {
if (loader != null) {
return loader.loadClass(className);
} else {
return ScriptRuntime.loadClassName(className);
}
} catch (ClassNotFoundException ex) {
} catch (SecurityException ex) {
Class cl = null;
if (loader != null) {
try { cl = loader.loadClass(className); }
catch (ClassNotFoundException ex) { }
catch (SecurityException ex) { }
} else {
try { cl = Class.forName(className); }
catch (ClassNotFoundException ex) { }
catch (SecurityException ex) { }
}
return null;
return cl;
}
private String packageName;

Просмотреть файл

@ -41,7 +41,6 @@
package org.mozilla.javascript;
import java.lang.reflect.*;
import org.mozilla.classfile.DefiningClassLoader;
/**
* This is the class that implements the runtime.
@ -1799,7 +1798,7 @@ public class ScriptRuntime {
private static ScriptableObject getGlobal(Context cx) {
try {
Class globalClass = loadClassName(GLOBAL_CLASS);
Class globalClass = Class.forName(GLOBAL_CLASS);
Class[] parm = { Context.class };
Constructor globalClassCtor = globalClass.getConstructor(parm);
Object[] arg = { cx };
@ -2004,29 +2003,11 @@ public class ScriptRuntime {
private static Class getClassOrNull(String className) {
try {
return loadClassName(className);
return Class.forName(className);
} catch (ClassNotFoundException ex) {
return null;
} catch (SecurityException ex) {
}
}
public static Class loadClassName(String className)
throws ClassNotFoundException
{
try {
ClassLoader cl = DefiningClassLoader.getContextClassLoader();
if (cl != null)
return cl.loadClass(className);
} catch (SecurityException e) {
// fall through...
} catch (ClassNotFoundException e) {
// Rather than just letting the exception propagate
// we'll try Class.forName as well. The results could be
// different if this class was loaded on a different
// thread than the current thread.
// So fall through...
}
return Class.forName(className);
return null;
}
static boolean hasProp(Scriptable start, String name) {