【问题标题】:log4j and the thread context classloaderlog4j 和线程上下文类加载器
【发布时间】: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


【解决方案1】:

您似乎偶然发现了 log4j(和 Apache Commons Logging 库)的主要问题,即它们在使用正确的类加载器时很难发现并与之交互。有一个非常密集的解释,并附有示例,here;带回家的信息是,新日志框架SLF4J 的主要驱动力之一是完全消除这些问题。您可能想换掉它,看看您的生活是否变得更轻松。

【讨论】:

  • 我不确定我们现在开始使用其他东西是否可行。处理这个 log4j 问题的建议方法是什么?
  • 老实说,我不能说,因为这是一个非常糟糕的问题,我现在努力避免使用 log4j 和 Apache Commons Logging。但实际上,您应该能够轻松地迁移到 SLF4J —— 请参阅slf4j.org/legacy.html 了解有关 SLF4J 如何带有“桥适配器”的信息,这些适配器允许您的代码仍然调用 log4j 并让这些调用被 SLF4J 拦截。这样,您可以在任何新代码中本地使用 SLF4J,并在闲暇时将使用 log4j 的旧代码迁移到 SLF4J。
  • +1 提示避免使用 Log4j 和 JCL。它们被 SLF4j 取代,它还具有 log4j 和 jcl 的兼容层。正是出于这些原因,我们在所有项目中都这样做了。
  • 你有文章解释为什么要避免使用 log4j 吗?如果没有背景,我真的无法提出这样的建议。还有一些关于 SLF4j 作为新“标准”的信息可以提供帮助。
  • Daniel,链接的文章(“密集解释”链接)解释了问题,你遇到的问题应该是最好的例子。
猜你喜欢
  • 2010-12-18
  • 2020-12-09
  • 1970-01-01
  • 2011-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多