Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.apache.log4j.Log4jLoggerFactory解决方法

今天在搭建一个项目单元测试环境跑测试用例的时候遇到了致命错误:
Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.apache.log4j.Log4jLoggerFactory
这个是什么情况?
翻看控制台输出信息看到一段:
SLF4J: Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar on the class path, preempting StackOverflowError.
SLF4J: See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more details.

翻看了上面说的网站提示信息:
The purpose of slf4j-log4j12 module is to delegate or redirect calls made to an SLF4J logger to log4j. The purpose of the log4j-over-slf4j module is to redirect calls made to a log4j logger to SLF4J. If SLF4J is bound with slf4j-log4j12.jar and log4j-over-slf4j.jar is also present on the class path, a StackOverflowError will inevitably occur immediately after the first invocation of an SLF4J or a log4j logger.

意思是slf4j-log4j12是用来代理或者重定向调用使一个SLF4J的日志通过log4j输出,log4j-over-slf4j的目的是将log4j的日志重定向输出到SLF4J,如果它俩在一个class path下造成StackOverflow的错误,因为它俩会陷入一个死循环。如果不明白SLF4J和log4j的同学可以转到:http://www.importnew.com/7450.html 仔细阅读。

于是我寻找了项目的maven依赖,发现有3个依赖中出现了slf4j-log4j12.jar,在每个依赖里加上:

<exclusion>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
</exclusion>

最终解决了问题。

再次跑测试用例的时候,还有一堆报错也不见了:
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/wangzhiang/.m2/repository/ch/qos/logback/logback-classic/1.1.3/logback-classic-1.1.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/wangzhiang/.m2/repository/org/slf4j/slf4j-log4j12/1.6.1/slf4j-log4j12-1.6.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]

原因是:SLF4J会在编译时会绑定import org.slf4j.impl.StaticLoggerBinder; 该类里面实现对具体日志方案的绑定接入。任何一种基于SLF4J的实现都要有一个这个类。如:slf4j-log4j12-1.6.1提供对log4j的一种适配实现。我的项目中存在logback-classic-1.1.3和slf4j-log4j12-1.6.1两个实现SLF4J的包同时出现,就出现了上面的报错,加上依赖的exclusion去掉slf4j-log4j12即可。

 

Tonitech版权所有 | 转载请注明出处: http://www.tonitech.com/2464.html

发表评论