我是Java的新手,刚开始学习类加载器的概念。目前我在使用log4j时遇到了一些问题,涉及到线程上下文类加载器的使用。
我得到了以下错误信息:"org.apache.log4j.ConsoleAppender"对象无法分配给"org.apache.log4j.Appender"变量。类"org.apache.log4j.Appender"由[java.net.URLClassLoader@105691e]加载,而类型为"org.apache.log4j.ConsoleAppender"的对象由[sun.misc.Launcher$AppClassLoader@16930e2]加载。无法实例化名为"CONSOLE"的appender。
我的应用程序大致工作方式如下:在初始化时,构造URLClassLoader#1并加载一些类,这些类使用log4j。稍后构造URLClassLoader#2(其父级为URLClassLoader#1)并加载一些更多的类,这些类也使用log4j。当使用URLClassLoader#2来加载这些类时,以上错误消息会出现(还有几个具有相同问题的错误)。
我当前的解决方法是,在加载有问题的类之前将当前线程上下文类加载器设置为URLClassLoader#2,并在加载完毕后将其重置为旧的类加载器:
ClassLoader urlClassLoader; // this is URLClassLoader #2
Thread thread = Thread.currentThread();
ClassLoader loader = thread.getContextClassLoader();
thread.setContextClassLoader(urlClassLoader);
try {
urlClassLoader.loadClass(...)
} finally {
thread.setContextClassLoader(loader);
}
虽然这种方法可以工作,但我不确定这是否是正确的方法。
有关此问题的任何见解将不胜感激。另外,为什么log4j强制我使用线程上下文类加载器?为什么不让我传递一个类加载器(当我不使用时使用默认值)而不是使用线程上下文类加载器?