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

时间:2010-03-01 05:34:09

标签: java multithreading classloader contextclassloader name-conflict

我编写了一个自定义类加载器'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 个答案:

答案 0 :(得分:2)

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

因此,您需要确保链接的类与链接类位于同一个类加载器实例(或父类)中。