【发布时间】:2011-01-29 14:04:13
【问题描述】:
我正在尝试为 Log4J 配置自定义布局类,如 my previous post 中所述。该类使用java.util.regex.Matcher 来识别日志消息中的潜在信用卡号。它可以在单元测试中完美运行,也可以在包含单个 servlet 的最小 Web 应用程序中运行。但是,当我尝试在 JBoss 中使用我们的应用程序部署它时,我收到以下错误:
--- MBEANS THAT ARE THE ROOT CAUSE OF THE PROBLEM ---
ObjectName: jboss.web.deployment:war=MyWebApp-2010_02-SNAPSHOT.war,id=476602902
State: FAILED
Reason: java.lang.LinkageError: java/util/regex/Matcher
我什至找不到关于这种形式的错误的任何信息 - 通常 LinkageError 似乎显示“加载程序约束违规”消息,例如在 here 中。
技术细节:我们使用 JBoss 4.2、Java 5、Log4J 1.2.12。我们将我们的应用程序部署在一个 .ear 中,其中包含(以及其他)上面提到的 .war 文件,以及一个单独的 jar 文件中的自定义布局类(我们称之为 Commons)。我们使用位于不同文件夹中的自己的log4j.properties 覆盖jboss-log4j.xml 中的默认设置,该文件夹在启动时添加到类路径中,并通过Sapient's Carbon framework 提供。
更新@skaffman 的回答:
我们有一个单独的 log4j.properties 文件的原因是 Sapient Carbon 传播的方案。这基本上将配置和数据文件从应用程序服务器环境中分离出来,因此它们可以通过 Carbon 的查找功能访问,并且可以存储在应用程序服务器外部的目录中。我们继承了这种设置,但我们讨厌它,因为它不符合 JEE 约定,因此在部署、类路径问题等方面给我们带来了很多麻烦。从长远来看,我们的目标是摆脱它,但这需要时间:-(
尽管单独的 log4j.properties 文件不是最佳实践,但它确实有效。它已经在我们的应用程序中运行了多年,我还可以使它与包含单个 servlet(不使用 Sapient Carbon)的简约 Web 应用程序一起工作。如果将 log4j.properties 放入类路径,Log4J 会在 Web 应用程序启动时正确读取它,并相应地重新配置日志记录。
更新#2: 一个有趣的发现是 Matcher 甚至没有在 MyWebApp 中使用,仅在 Commons 模块(和另一个模块,在单独的 jar 中)中使用。在 Commons 中,之前在一个名为 StringHelper 的类中使用过,MyWebApp 通过其他模块间接使用该类。
我想这排除了由不同类加载器加载两个不同 Matcher 类版本的可能性。所以我唯一剩下的猜测是,当从 jar 和 war 中使用 Matcher 时,它由两个不同的类加载器加载,然后尝试从一个传递到另一个。这由Frank Kieviet's excellent article 解释。但是,我相信这样的设置会导致“违反加载程序约束”而不是这种形式的错误。
更新#3:如果我在 jboss-log4j.xml 中添加 this appender (example 3.8),错误就会消失,服务器运行完美 :-o 这显然与加载 log4j.jar 有关系,因为此设置要求 jar 存在于服务器 lib 目录中。如果我将附加程序类型更改为org.jboss.logging.appender.FileAppender,并将日志级别设置为WARN,它也可以工作,这会导致ucl.log 文件为空。这可能适合作为临时解决方法,但我仍然渴望完全了解这里发生了什么。
此错误消息是什么意思,我该如何正确解决?
结语
经过漫长的等待,我终于从日志进程中删除了 Carbon,并将我们的日志配置迁移到 server/conf/jboss-log4j.xml。这要求我在 server/lib 目录中的单独 jar 中发布我们的自定义日志过滤器类。在此之后,类加载再次工作,没有上面 Update#3 中描述的解决方法:-)
【问题讨论】:
-
删除了
carbon标签 - 用于 MacOSX API。 -
@skaffman 很遗憾,存在名称冲突 :-( 感谢您指出这一点。从现在开始,我将“我们的”框架称为“Sapient Carbon”。
-
一篇很有用的文章:ibm.com/developerworks/views/java/…
标签: java jboss log4j classloader