Maven依赖冲突解决

背景

在部署一个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一下,否则可能会有之前的依赖还保留在里面。

    原文作者:韩思明
    原文地址: https://www.jianshu.com/p/fb652af5349c
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞