【发布时间】:2009-12-29 13:45:24
【问题描述】:
我是 Java 新手,刚刚开始了解类加载器的概念。现在我在 log4j 使用线程上下文类加载器方面遇到了一些问题。
我收到以下错误:A "org.apache.log4j.ConsoleAppender" object is not assignable to a "org.apache.log4j.Appender" variable. The class "org.apache.log4j.Appender" was loaded by [java.net.URLClassLoader@105691e] whereas object of type "org.apache.log4j.ConsoleAppender" was loaded by [sun.misc.Launcher$AppClassLoader@16930e2]. Could not instantiate appender named "CONSOLE".
我的应用程序大致是这样工作的:在初始化 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 强迫我弄乱线程上下文类加载器?为什么不让我传入一个类加载器(并在我不这样做时使用默认的)而不是使用线程的那个?
【问题讨论】:
-
你的问题救了我的命,我被类似的问题困了 3 天!我还没有设置“thread.setContextClassLoader”,这样就可以了!尽管您是 java 新手,但它真的很棒!
标签: java log4j classloader