ContextClassLoader没有挂钩

时间:2010-08-08 03:44:54

标签: java

我正在尝试定义自定义的ClassLoader。

public class ExampleLoader extends ClassLoader
{
    public Class<?> findClass(String name) throws ClassNotFoundException
    {
        System.out.println("This never gets printed");
        return super.findClass(name);
    }

    public Class<?> loadClass(String name, boolean b)
        throws ClassNotFoundException
    {
        System.out.println("This never gets printed");
        return super.loadClass(name, b);
    }
}

当然还有我的代码来测试它:

public class Tester
{
    public static void main(String[] args)
    {
        Thread t = new FooThread();
        t.setContextClassLoader(new ExampleLoader());
        t.start();
    }
}

class FooThread extends Thread
{
    public void run()
    {
        new RandomClass();
    }
}

问题是我的线条永远不会被打印出来。显然我错过了什么。

2 个答案:

答案 0 :(得分:6)

这与bug 4868493有关。这是一个相关的引用:

  

不幸的是getContextClassLoadersetContextClassLoader的文档   ClassLoader可能导致人们得出结论   提交者的代码应该按预期工作。

     

但是,类加载中有一个基本规则 - 没有类可以   自动加载一个“下游”的类,即不能   由该类ClassLoaders或其祖先之一直接加载   Thread.getContextClassLoader

     

这在许多地方都有描述。例如,冥想   白皮书在这里:   http://www.javageeks.com/Papers/ClassForName/index.html   获得启蒙。

     

关键点似乎是没有使用上下文类加载器   由Java语言自动完成。这只是一个传统的地方   存储上下文类加载器,以便其他类可以使用它   3-argument form of Class.forName

     

Thread.setContextClassLoadernew RandomClass()的规范   应该澄清,“上下文类加载器”的含义应该   澄清一下。重新归类为doc bug。

该规范尚未澄清。

要让它按照您最初的要求工作,请将<{1}}替换为

Class.forName(RandomClass.class.getName(), 
              true,
              getContextClassLoader()).newInstance();

这反映了以下内容:

This never gets printed

答案 1 :(得分:0)

通常,JVM中的所有类加载器都按层次结构组织,以便每个类加载器(引导整个JVM的原始类加载器除外)都具有单个父级。当被要求加载一个类时,每个兼容的类加载器都应该首先将加载委托给它的父级,并且只有在父级失败时才尝试定义该类。

在你的情况下也会发生同样的事情。要加载“RandomClass”,ContextClassLoader委托给它的父级,依此类推。其中一个父类加载器能够加载“RandomClass”(RandomClass在父类的路径中)。由于这个原因,你的SOP没有出现。

参考以下文章有点旧但很好:

http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html?page=1