背景
在部署一個spring-boot項目到遠程測試機上的tomcat之后毙玻,發(fā)現(xiàn)tomcat并沒有啟動起來础米,讓我折騰了近2個小時其骄,現(xiàn)在將解決思路以及解決方法記錄下來啃奴,下次在遇到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,成功焚鲜。
注意
在執(zhí)行mvn的命令掌唾,如update,install之前忿磅,必須要先clean一下糯彬,否則可能會有之前的依賴還保留在里面。