Changement de chargeur de classe
Je suis en train de basculer le chargeur de classe au moment de l'exécution:
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();
}
}
et:
public class TestProxy {
public void test() {
ClassLoader tcl = Thread.currentThread().getContextClassLoader();
ClassLoader ccl = ClassToLoad.class.getClassLoader();
ClassToLoad classToLoad = new ClassToLoad();
}
}
(InjectingClassLoader est une classe étendant la org.apache.bcel.util.Chargeur de classe qui doit charger les versions modifiées de classes avant de lui demander de parent pour eux)
Je tiens à rendre le résultat de "1" et "méthode 2" exactement les mêmes, mais il semble que fil.setContextClassLoader(classLoader) ne fait rien et la "méthode 2" utilise toujours le système de chargeur de classes (peut être déterminé par la comparaison des tcl et de la ccl variables pendant le débogage).
Est-il possible de faire tous les classes chargées par le nouveau thread utilisation du chargeur de classe?
OriginalL'auteur Chris | 2010-05-12
Vous devez vous connecter pour publier un commentaire.
La classe anonyme vous créez via
new Thread("test") { ... }
a une référence implicite à l'enfermant instance. Classe littéraux à l'intérieur de cette classe anonyme sera chargé à l'aide de la classe englobante du chargeur de classe.Afin de faire fonctionner ce test, vous devriez sortir un bon Exécutable de mise en œuvre, et la charge de reflectively à l'aide de l'souhaité chargeur de classe; puis de passer explicitement le fil. Quelque chose comme:
Fixe; le réflexe d' -> reflectively. Merci.
OriginalL'auteur Patrick Schneider
Je pense que InjectingClassLoader peut être important ici. Rappelez-vous comment classloading délégation œuvres - si plus d'un chargeur de classe de votre hiérarchie pouvez trouver la classe, le plus haut du chargeur de classe sera celle qui se charge. (Voir La Figure 21.2 ici)
Depuis InjectingClassLoader ne spécifiez pas un parent dans son constructeur, il sera par défaut le constructeur, dans l'abstrait, chargeur de classe, ce qui permettra de définir le contexte actuel du chargeur de classe comme InjectingClassLoader du parent. Par conséquent, puisque le parent (ancien cadre du chargeur de classe) peut trouver TestProxy, il charge toujours la classe avant de InjectingClassLoader obtient une chance de le faire.
Juste vérifié la source et org.apache.bcel.utilClassloader toujours s'étend java.lang.Chargeur de classe...
La valeur par défaut de la classe loader constructeur utilise des chargeurs de classes.getSystemClassLoader(), pas de Fil.currentThread().getContextClassLoader(), comme le chargeur de classe parent.
OriginalL'auteur G__