问题是,在腾迅云上tomcat启动报错,错误日志如下:
26-Dec-2017 15:02:10.499 严重 [localhost-startStop-1] org.apache.catalina.core.StandardContext.listenerStart Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener java.lang.StackOverflowError at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936) at org.apache.log4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:39) at org.apache.log4j.LogManager.getLogger(LogManager.java:45) at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:66) at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:270) at org.apache.log4j.Category.<init>(Category.java:57) at org.apache.log4j.Logger.<init>(Logger.java:37) at org.apache.log4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:43) at org.apache.log4j.LogManager.getLogger(LogManager.java:45) at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:66) at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:270) at org.apache.log4j.Category.<init>(Category.java:57) at org.apache.log4j.Logger.<init>(Logger.java:37)
以为是服务器问题,就在本地启动,本地正常,然后十分郁闷,索性在阿里云上启动,错误依旧。仔细看下tomcat的日志,会发现如下几句:
SLF4J: Found binding in [jar:file:/root/application/tomcat-8.0.43-mp/webapps/ROOT/WEB-INF/lib/activemq-all-5.9.0.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/root/application/tomcat-8.0.43-mp/webapps/ROOT/WEB-INF/lib/logback-classic-1.1.2.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 [org.slf4j.impl.Log4jLoggerFactory]
之后访问官方说明,在下面看到了说明,Detected both jcl-over-slf4j.jar AND slf4j-jcl.jar on the class path, preempting StackOverflowError. 但奇怪的是,我项目中没有使用slf4j-jcl.jar,我用的是log4j-over-slf4j-1.7.20.jar,log4j-1.2.17.jar,activemq-all-5.9.0.jar。后来看到一篇博客,讲解了jar包在classpath里的顺序不同可能导致问题,索性把log4j-1.2.17.jar删除了(其实不用删除,在名字后加个bak就行了),再执行,依旧报错,跟踪代码的Logger定义,发现在activemq-all-5.9.0.jar中!!!删除该jar包,问题解决。
所以:
- 我这个项目改用logback时原项目中已有activemq了,是从别处复制过来的,也没有什么用,就直接删除了,大家有需要的还得去研究一下activemq-all的替换jar。
- 使用jar包里时不要轻易使用-all版本的,里面可能把其它类集成进去了。
- 项目既然使用了slf4j,就不要再使用log4j的jar包了,使用log4j-over-slf4j就好了。
- 出错了先不要百度搜索,先仔细看看日志。
- over。
附上使用的pom
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.9.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.7.20</version>
</dependency>