Jena + spring boot + tomcat: Class path contains multiple SLF4J bindings错误及解决

错误现象:
调用Jena库函数的war包部署到tomcat,tomcat重启后logs/catalina.out中提示,
……
……
1:SLF4J: Class path contains multiple SLF4J bindings.
2:SLF4J: Found binding in [jar:file:/home/sc/apache-tomcat-8.0.30/webapps/kbdemo/WEB-INF/lib/slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
3:SLF4J: Found binding in [jar:file:/home/sc/apache-tomcat-8.0.30/webapps/kbdemo/WEB-INF/lib/logback-classic-1.1.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
4:SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
5:SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
6:SLF4J: Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar on the class path, preempting StackOverflowError.
7:SLF4J: See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more details.
……
……
Caused by: java.lang.IllegalStateException: Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar on the class path, preempting StackOverflowError. See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more details.
……

错误分析:
1)看提示,有多个log4j的jar包可用,如第2和第3行所示,tomcat启动时无法正确解析,但也会选择一个,如第5行。
2)分析工程生成的war包中包含的jar文件(在war包解压后的WEB-INF/lib/目录下)。
没有引入Jena库时,log4j相关的jar文件是4个,
log4j-api-2.4.1.jar
log4j-core-2.4.1.jar
log4j-over-slf4j-1.7.12.jar
slf4j-api-1.7.12.jar

引入jena库后,log4j相关的jar文件增加到6个,新增加的2个如加粗字体所标示。
log4j-1.2.17.jar
log4j-api-2.4.1.jar
log4j-core-2.4.1.jar
log4j-over-slf4j-1.7.12.jar
slf4j-api-1.7.12.jar
slf4j-log4j12-1.7.12.jar

简单解决方法:
1)参考http://stackoverflow.com/questions/12494420/class-path-contains-multiple-slf4j-bindings
2)删除webapps/kbdemo/WEB-INF/lib/lslf4j-log4j12-1.7.2.jar文件
3)重新启动tomcat服务即可

错误原因:
http://www.slf4j.org/codes.html#multiple_bindings中指出,
Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar on the class path, preempting StackOverflowError.

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 withslf4j-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.

在上文的故障分析时我们注意这两个文件log4j-over-slf4j-1.7.12.jar和slf4j-log4j12-1.7.12.jar同时存在。根据上段文字的描述,它们的作用如下图所示,它们同时存在会造成循环依赖。
slf4j-log4j12
SLF4J ———–> log4j
<———–
log4j-over-slf4j

高级解决方法:
如何在引入Jena库时不包含slf4j-log4j12-1.7.12.jar呢?
在gradle的配置文件build.gradle中进行配置说明,排除掉这个jar包,方法如下:

dependencies{
……
compile(‘org.apache.jena:apache-jena:3.0.1’)
……
configurations {
all*.exclude group: “org.slf4j”, module: “slf4j-log4j12”
}
使用gradle重新编译,war包中就不包含slf4j-log4j12-1.7.12.jar文件了。

你可能感兴趣的:(tomcat)