一、实战环境:
win10 64位操作系统 + idea 2020.2.3 + maven 3.6.3 + jdk 8 + springBoot 2.0.4.RELEASE
二、场景还原:
项目引入某个jar包后,启动项目,报了Exception in thread “main” java.lang.StackOverflowError,原因是jar包依赖冲突,从而导致StackOverflowError,具体报错如下:
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/D:/zxj/mavenRepository/org/apache/logging/log4j/log4j-slf4j-impl/2.10.0/log4j-slf4j-impl-2.10.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/D:/zxj/mavenRepository/ch/qos/logback/logback-classic/1.2.3/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.apache.logging.slf4j.Log4jLoggerFactory]
Exception in thread "main" java.lang.StackOverflowError
at org.apache.logging.log4j.util.StackLocator.getCallerClass(StackLocator.java:125)
三、原因分析:
log4j-slf4j-impl-2.10.0.jar 和 logback-classic-1.2.3.jar 出现了全限定名相同的类:/org/slf4j/impl/StaticLoggerBinder.class,从而发生了jar包冲突(即 jar hell)
四、解决过程:
- 排查了一下pom文件,并没有直接引入这两个jar,所以显然是pom文件引入的jar有依赖了这两个jar。
- 打开 pom 文件,点击 “Dependency Analyzer”,选择“All Dependencies as Tree”,搜索“logback”和“log4j”即可看到对应依赖该jar的是哪些jar(需要安装 idea插件 Maven Helper)
- 由于我是需要用到logback-classic-1.2.3.jar,所以需要排除掉log4j-slf4j-impl-2.10.0.jar。那么搜索“log4j-slf4j-impl”,右键“exclude”,即在pom.xml,将看到如下的Exclude规则:
<dependency>
<groupId>com.xx.xx.main</groupId>
<artifactId>xx-xx-main-service</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<artifactId>log4j-slf4j-impl</artifactId>
<groupId>org.apache.logging.log4j</groupId>
</exclusion>
</exclusions>
</dependency>
因为我这边搜索"log4j-slf4j-impl"出来的依赖树如下:
- xx-xx-main-service:1.0
- xx-openapi:1.0.4
- spring-boot-starter-log4j2:2.0.4.RELEASE
- log4j-slf4j-impl:2.10.0
- 此时,重启服务成功,已经不报jar包冲突了。
五、总结:
- 查看项目jar包依赖关系,idea使用插件“Maven Helper”,而eclipse的话,点开项目中的pox.xml文件的dependency hierarchy选项卡;
- 根据找到的依赖,在对应pom.xml中,使用标签进行排除依赖;
- idea 2020.X版本之后不会自动更新依赖,在修改了pom.xml文件之后,会有一个"maven update"的蓝色小图标在右上角,需要自己手动点击进行更新,由于之前的版本会自动更新依赖,所以换到2020.X版本之后,没注意到这个问题,导致各种小问题的出现。
参考链接:
- https://blog.csdn.net/blueheart20/article/details/80363870(Spring Boot 2.0下配置Log4j2下的错误问题分析与解决)
- https://blog.csdn.net/ycccsdn/article/details/90549347(jar包冲突原因分析)
- https://www.zhangshengrong.com/p/boNwZexMaw/(idea 升级到 2020.x 版后,变更 MAVEN 不会自动更新依赖)