彻底搞明白为什么日志框架依赖冲突了

项目启动报错如下:

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
qdc is restarting
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=1024M; support was removed in 8.0
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/xxx/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/xxx/lib/logback-classic-1.2.3.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]
log4j:WARN No appenders could be found for logger (com.qihoo.bigdata.foundation.spring.startup.OnStartup).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Exception in thread "main" 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:/xxx/lib/slf4j-log4j12-1.7.25.jar). If you are using WebLogic you will need to add 'org.slf4j' to prefer-application-packages in WEB-INF/weblogic.xml: org.slf4j.impl.Log4jLoggerFactory
        at org.springframework.util.Assert.instanceCheckFailed(Assert.java:637)
        at org.springframework.util.Assert.isInstanceOf(Assert.java:537)
        at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLoggerContext(LogbackLoggingSystem.java:286)
        at org.springframework.boot.logging.logback.LogbackLoggingSystem.beforeInitialize(LogbackLoggingSystem.java:102)
        at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationStartingEvent(LoggingApplicationListener.java:191)
        at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:170)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
        at org.springframework.boot.context.event.EventPublishingRunListener.starting(EventPublishingRunListener.java:68)
        at org.springframework.boot.SpringApplicationRunListeners.starting(SpringApplicationRunListeners.java:48)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1258)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246)

系统发现了多个日志实现,最终因为张冠李戴而发生了异常。
这种很常见,而且在建项目和后期开发过程,很容易无意中引入的jar间接带入另一个日志实现,从而引起日志框架的冲突。

为什么会冲突呢?

笔者通过maven helper这个IDEA插件来分析依赖:
彻底搞明白为什么日志框架依赖冲突了_第1张图片
如上图所示,在依赖中发现了两个日志实现框架,两个桥接器jar包。笔者用一个更加直观的图来展示发生了什么
彻底搞明白为什么日志框架依赖冲突了_第2张图片
目前依赖为log4j-api提供了两种日志实现:第一种很直接是logback,第二种经过混乱的桥接,兜兜转转最终找到了log4j。

怎么解决呢?

排除掉一种实现即可。
这里面有讲究,日志接口更倾向于使用更加通用的框架slf4j-api,而不是log4j-api。
因为slf4j能适配几乎所有的日志实现,比如log4j、jul、logback等等
彻底搞明白为什么日志框架依赖冲突了_第3张图片
而log4j-api仅仅是log4j这个日志框架的门面,通用性不好。

方案一(最优)

  1. 先将log4j-api换成slf4j-api
  2. 排除log4j、slf4j-logj12

使用slf4j-api门面,实现选用logback,后期可以任意切换实现

方案二

  1. 排除logback-xx
  2. 排除log4j-to-slf4j、slf4j-log4j12

使用log4j-api门面,使用log4j作为固定实现。通用性不好,绑死了log4j日志框架。

你可能感兴趣的:(Spring,Boot,slf4j,log4j,日志冲突,依赖冲突)