1

J'ai écrit un classloader personnalisé 'JarClassLoader', qui se fonctionne bien, puisque le cas de test suivant est vert:Pourquoi Java ne peut-il pas utiliser le classloader de contexte de threads lorsqu'une méthode est littéralement appelée?

public void testJarClassLoader() throws Exception 
{ 
    JarClassLoader cl = new JarClassLoader(); 
    cl.addURLsByClassPath("lib/a-lot-of-jars.jar|lib/more-jars.jar", "\\|"); 

    Class c = cl.loadClass("com.packagepath.classname"); 

    assertNotNull(c); 

    System.out.println("Class: "+ c); 
} 

Mais, le cas de test suivant ne fonctionnerait pas:

public void testSetThreadClassLoader() throws Exception 
{ 
    JarClassLoader cl = new JarClassLoader(); 
    cl.addURLsByClassPath("lib/a-lot-of-jars.jar|lib/more-jars.jar", "\\|"); 

    Thread t = new Thread() { 
     public void run() 
     { 
      TestCase.assertEquals("com.packagepath.JarClassLoader", 
        Thread.currentThread().getContextClassLoader().getClass().getName()); 
      //this assertion passed 


      try 
      { 
       Class c = Class.forName("com.packagepath.classname"); 

       //it doesn't work, throws ClassNotFoundException 

       TestCase.assertNotNull(c); 
      } 
      catch (ClassNotFoundException e) 
      { 
       e.printStackTrace(); 
      } 

      **com.packagepath.classname.methodname("params");** 
      //it doesn't work, throws java.lang.ClassNotFoundException 
     } 
    }; 

    t.setContextClassLoader(cl); 
    t.start(); 
} 

remarquez la ligne regardée, j'ai voulu utiliser le classloader de contexte de fil quand j'appelle littéralement une méthode.

J'ai lu des dizaines de pages Web et de documents, aucun d'entre eux ne me dit certainement si la ligne en gras devrait fonctionner ou non. Je ne peux pas comprendre où s'est mal passé.

Est-ce que la méthode littéralement appelée useloader permet de charger la classe correspondante? Si non, pourquoi pas? J'en ai besoin pour travailler, car l'appel dans les pots fournis par les vendeurs est littéralement, n'utilisant pas de réflexion ou quoi que ce soit d'autre, et je dois assigner différents chargeurs de classes pour différents threads afin d'éviter les collisions de noms.

Quelqu'un peut-il m'aider? Merci un million!

Répondre

2

Chaque classe est liée à d'autres classes en utilisant son propre chargeur de classes. Les chargeurs de classe délèguent généralement à leurs parents. Vous ne pouvez pas modifier le chargeur de classe de contexte de thread et attendre que la classe soit dissociée et reliée à différentes classes.

Vous devez donc vous assurer que la classe liée est dans la même instance de chargeur de classe (ou un parent) que la classe de liaison.

+0

Merci pour votre réponse. Je ne m'attendais pas à le dissocier, j'ai mis un classpath avec essentiellement rien, donc la classe n'a jamais été chargée avant d'entrer dans le fil. Je voulais juste le lier pour la première fois. – Utensil

+0

Donc vous attendiez que le lien se produise en fonction du thread sur lequel il s'est passé à ce moment-là? Cela ne fonctionnerait pas très bien non plus. –

+0

Merci, mais ce dont j'ai besoin n'est pas une évaluation "ne fonctionnerait pas très bien" mais une certaine réponse à propos de can and cant, basée sur une connaissance approfondie de classloader de contexte de thread java. En fait, j'ai vu des codes dans Tomcat et d'autres choses matures qui peuvent dissocier et lier, pas mentionner juste le lier pour une fois. – Utensil