Ändern classloader
Ich versuche, schalten Sie den class loader zur Laufzeit:
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();
}
}
und:
public class TestProxy {
public void test() {
ClassLoader tcl = Thread.currentThread().getContextClassLoader();
ClassLoader ccl = ClassToLoad.class.getClassLoader();
ClassToLoad classToLoad = new ClassToLoad();
}
}
(InjectingClassLoader ist eine Klasse, die sich die org.apache.bcel.util.ClassLoader dem laden sollte die modifizierte Versionen der Klassen, bevor Sie Fragen, es ist der Eltern für Sie)
Ich möchte gern das Ergebnis von "Methode 1" und "Methode 2" genau das gleiche, aber es sieht aus wie thread.setContextClassLoader(classLoader) nichts tut und die "Methode 2" verwendet immer den system-classloader (können bestimmt werden durch den Vergleich von tcl und ccl Variablen während des Debuggens).
Ist es möglich, alle Klassen geladen neuen thread angesichts classloader?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Anonyme Klasse, die Sie erstellen, über
new Thread("test") { ... }
hat eine implizite Referenz auf die umschließende Instanz. Class-Literale innerhalb dieser anonymen Klasse wird geladen, mit Hilfe der umschließenden Klasse ClassLoader.Damit der test funktioniert, sollten Sie ziehen eine richtige Runnable-Implementierung, und laden Sie es nachdenklich mit der gewünschten ClassLoader; dann passieren, dass explizit auf den thread. So etwas wie:
Ich denke InjectingClassLoader kann wichtig sein hier. Denken Sie daran, wie Sie zum laden von Klassen-delegation funktioniert - wenn mehrere classloader, die in der Hierarchie finden das Klasse, der top-die meisten classloader wird sein, die Lasten. (Siehe Abbildung 21.2 hier)
Seit InjectingClassLoader nicht angeben, ein Elternteil in seinem Konstruktor, es wird standardmäßig auf den Konstruktor in der abstrakten ClassLoader, der die aktuelle Kontext-classloader als InjectingClassLoader Eltern werden. Deshalb, weil der Elternteil (alt Kontext-classloader) finden TestProxy, ist es immer zu Lasten der Klasse vor InjectingClassLoader eine chance bekommt.