背景
在部署一个spring-boot项目到远程测试机上的tomcat之后,发现tomcat并没有启动起来,让我折腾了近2个小时,现在将解决思路以及解决方法记录下来,下次在遇到Maven依赖冲突之后,能够很快的解决。
解决思路
查看tomcat日志
因为tomcat启动失败,所以首先查看tomcat打印出来的相关日志。
tail -n 500 {TOMCAT_HOME}/logs/catalina.2017-08-08.log
里面确实有错误日志,其中这个错误日志引起的我的注意。
Caused by: java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.slf4j.impl.Log4jLoggerFactory loaded from file:/export/App/apache-tomcat-8.5.16/webapps/k8s-api/WEB-INF/lib/slf4j-log4j12-1.7.5.jar). If you are using WebLogic you will need to add 'org.slf4j' to prefer-application-packages in WEB-INF/weblogic.xml Object of class [org.slf4j.impl.Log4jLoggerFactory] must be an instance of class ch.qos.logback.classic.LoggerContext
at org.springframework.util.Assert.isInstanceOf(Assert.java:346)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLoggerContext(LogbackLoggingSystem.java:221)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLogger(LogbackLoggingSystem.java:213)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.beforeInitialize(LogbackLoggingSystem.java:98)
at org.springframework.boot.logging.LoggingApplicationListener.onApplicationStartedEvent(LoggingApplicationListener.java:216)
at org.springframework.boot.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:198)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:163)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:136)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:119)
at org.springframework.boot.context.event.EventPublishingRunListener.publishEvent(EventPublishingRunListener.java:111)
at org.springframework.boot.context.event.EventPublishingRunListener.started(EventPublishingRunListener.java:60)
at org.springframework.boot.SpringApplicationRunListeners.started(SpringApplicationRunListeners.java:48)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at org.springframework.boot.context.web.SpringBootServletInitializer.run(SpringBootServletInitializer.java:149)
at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:129)
at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:85)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5196)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 10 more
关键的信息在这里
LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.slf4j.impl.Log4jLoggerFactory loaded from file:/export/App/apache-tomcat-8.5.16/webapps/k8s-api/WEB-INF/lib/slf4j-log4j12-1.7.5.jar).
大概就是说Logback已经在classpath中存在,这时候就应该意识到有Logback依赖冲突,在多个地方都有Logback的依赖。
我的pom.xml文件如下
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
...
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
使用maven命令,查看依赖树
mvn dependency:tree
查看结果
[INFO] +- org.springframework.boot:spring-boot-starter:jar:1.3.3.RELEASE:compile
[INFO] | +- org.springframework.boot:spring-boot:jar:1.3.3.RELEASE:compile
[INFO] | +- org.springframework.boot:spring-boot-autoconfigure:jar:1.3.3.RELEASE:compile
[INFO] | +- org.springframework.boot:spring-boot-starter-logging:jar:1.3.3.RELEASE:compile
[INFO] | | +- ch.qos.logback:logback-classic:jar:1.1.5:compile
[INFO] | | | \- ch.qos.logback:logback-core:jar:1.1.5:compile
[INFO] | | +- org.slf4j:jcl-over-slf4j:jar:1.7.5:compile
[INFO] | | +- org.slf4j:jul-to-slf4j:jar:1.7.5:compile
[INFO] | | \- org.slf4j:log4j-over-slf4j:jar:1.7.5:compile
[INFO] | +- org.springframework:spring-core:jar:4.2.5.RELEASE:compile
[INFO] | \- org.yaml:snakeyaml:jar:1.16:compile
...
[INFO] +- org.slf4j:slf4j-log4j12:jar:1.7.5:compile
[INFO] | \- org.slf4j:slf4j-api:jar:1.7.5:compile
可以从上面的结果中很清楚的看见org.slf4j:log4j-over-slf4j:jar:1.7.5这个包冲突了,所以我们只需要去掉其中一个Logback的依赖即可。
解决依赖冲突
如下方法可以去掉多余的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
再重新启动tomcat,成功。
注意
在执行mvn的命令,如update,install之前,必须要先clean一下,否则可能会有之前的依赖还保留在里面。