代码之家  ›  专栏  ›  技术社区  ›  Utensil

为什么java不能在字面上调用方法时使用线程上下文类加载器?

  •  1
  • Utensil  · 技术社区  · 15 年前

    我已经编写了一个自定义类加载器“JarClassLoader”,它本身工作正常,因为下面的测试用例是绿色的:

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

    注意开始的一行,我想在真正调用方法时使用线程上下文类加载器。

    字面上被调用的方法可以使用类加载器来加载相应的类吗?如果没有,为什么不能?我需要它来工作,因为供应商提供的jar中的调用是字面上的,而不是使用反射或其他任何东西,我必须为不同的线程分配不同的类加载器,以避免供应商jar中的名称冲突。

    有人能帮我吗?万分感谢!

    1 回复  |  直到 15 年前
        1
  •  2
  •   Tom Hawtin - tackline    15 年前

    每个类使用自己的类加载器链接到其他类。类装入器通常委托给它们的父类。您不能更改线程上下文类加载器并期望该类被取消链接并重新链接到不同的类。