1

Я написал специальный загрузчик классов «JarClassLoader», которая сама по себе работает нормально, так как следующий тест зеленый:Почему Java не может использовать поточный контекстный загрузчик классов при вызове метода буквально?

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); 
} 

Но, следующий тест не будет работать:

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(); 
} 

обратите внимание на скрытую строку, я хотел использовать загрузчик классов потоков, когда я буквально вызываю метод.

Я читал десятки веб-страниц и документов, но ни один из них не говорит мне, должна ли работать жирная линия или нет. Я не могу понять, где пошло не так.

Может ли буквально называть метод useloader загрузчиком соответствующего класса? Если нет, то почему? Мне нужно, чтобы это работало, поскольку вызов в банках, предоставляемых поставщиками, буквально не использует отражение или что-то еще, и я должен назначить разный загрузчик классов для разных потоков, чтобы избежать столкновения имен в банках поставщика.

Может кто-нибудь мне помочь? Бесконечно благодарен!

ответ

2

Каждый класс связывается с другими классами, используя собственный загрузчик классов. Погрузчики классов обычно передают своим родителям. Вы не можете изменить загрузчик классов контекста потока и ожидать, что класс будет отсоединен и повторно подключен к различным классам.

Таким образом, вам необходимо убедиться, что связанный класс находится в одном экземпляре загрузчика класса (или родительском) в качестве класса связывания.

+0

Спасибо за ваш ответ. Я не ожидал развязать его, я установил classpath в основном ничего, поэтому класс никогда не загружался, прежде чем вводить поток. Я просто хотел связать его в первый раз. – Utensil

+0

Итак, вы ожидали, что связь произойдёт в зависимости от того, в какой строке она работает в то время? Это тоже не сработает. –

+0

Спасибо, но мне нужна не оценка «не очень хорошо», а определенный ответ о can и can not, основанный на обширном знании java thread context classloader. На самом деле я видел коды в Tomcat и другие зрелые вещи, которые могут развязать и связать, не говоря уже о том, чтобы просто связать его на один раз. – Utensil

 Смежные вопросы

  • Нет связанных вопросов^_^