我试图在运行时切换类加载程序:
public class Test {
public static void main(String[] args) throws Exception {
final InjectingClassLoader classLoader = new InjectingClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
Thread thread = new Thread("test") {
public void run() {
System.out.println("running...");
// approach 1
ClassLoader cl = TestProxy.class.getClassLoader();
try {
Class c = classLoader.loadClass("classloader.TestProxy");
Object o = c.newInstance();
c.getMethod("test", new Class[] {}).invoke(o);
} catch (Exception e) {
e.printStackTrace();
}
// approach 2
new TestProxy().test();
};
};
thread.setContextClassLoader(classLoader);
thread.start();
}
}以及:
public class TestProxy {
public void test() {
ClassLoader tcl = Thread.currentThread().getContextClassLoader();
ClassLoader ccl = ClassToLoad.class.getClassLoader();
ClassToLoad classToLoad = new ClassToLoad();
}
}(InjectingClassLoader是一个扩展org.apache.bcel.util.ClassLoader的类,它应该在询问它的父类之前加载修改过的类的版本)
我想使“方法1”和“方法2”的结果完全相同,但是看起来thread.setContextClassLoader( classloader )什么也不做,而且“方法2”总是使用系统类加载器(可以通过调试时比较tcl和ccl变量来确定)。
是否有可能使所有的类都由新线程使用给定的类加载器加载?
发布于 2010-05-14 06:49:35
您通过new Thread("test") { ... }创建的匿名类有一个对封闭实例的隐式引用。这个匿名类中的类文本将使用封闭类的ClassLoader加载。
为了使测试工作正常,您应该提取一个合适的可运行实现,并使用所需的ClassLoader反射加载它;然后显式地将它传递给线程。类似于:
public final class MyRunnable implements Runnable {
public void run() {
System.out.println("running...");
// etc...
}
}
final Class runnableClass = classLoader.loadClass("classloader.MyRunnable");
final Thread thread = new Thread((Runnable) runableClass.newInstance());
thread.setContextClassLoader(classLoader); // this is unnecessary unless you you are using libraries that themselves call .getContextClassLoader()
thread.start();发布于 2010-05-12 19:39:59
我认为InjectingClassLoader在这里可能很重要。记住类加载委托是如何工作的--如果您的层次结构中有多个类加载器可以找到类,那么最顶层的类加载器就是加载类的类加载器。(见图21.2 这里)
由于InjectingClassLoader没有在其构造函数中指定父类,因此它将默认为抽象ClassLoader中的构造函数,这将将当前上下文类加载器设置为InjectingClassLoader的父类。因此,由于父类(旧的上下文类加载器)可以找到TestProxy,所以它总是在InjectingClassLoader有机会之前加载该类。
https://stackoverflow.com/questions/2822004
复制相似问题