如何解决项目中log4j与logback依赖版本冲突的问题?
摘要:问题回放: 问题本质分析 SLF4J 的角色:SLF4J 是一个日志门面(接口),它本身不记录日志,需要与一个具体的日志实现(如 Logback、Log4j2)绑定才能工作。 “多个提供程序”警告:你的项目中同时存在两个 SLF4J 的具体
问题回放:
问题本质分析
SLF4J 的角色:SLF4J 是一个日志门面(接口),它本身不记录日志,需要与一个具体的日志实现(如 Logback、Log4j2)绑定才能工作。
“多个提供程序”警告:你的项目中同时存在两个 SLF4J 的具体实现(绑定器):
◦ org.apache.logging.slf4j.SLF4JServiceProvider -> 来自 Log4j2 的 log4j-slf4j2-impl 包。
◦ ch.qos.logback.classic.spi.LogbackServiceProvider -> 来自 Logback 框架。
致命错误:最关键的错误信息是:
log4j-slf4j2-impl cannot be present with log4j-to-slf4j
这意味着项目中同时包含了 log4j-slf4j2-impl 和 log4j-to-slf4j 这两个互斥的JAR包。
◦ log4j-slf4j2-impl:让 Log4j2 作为 SLF4J 的实现。
◦ log4j-to-slf4j:将其他的 Log4j2 日志调用桥接(重定向)到 SLF4J。如果 SLF4J 的背后又是 Log4j2,就会形成循环依赖,这是被禁止的。
结论
项目依赖混乱,同时引入了 Logback 和 Log4j2 两套完整的日志体系,并且 Log4j2 自身的两个模块也发生了冲突,导致 SLF4J 无法决定使用哪一个提供者,最终引发初始化异常。
解决方案
核心思路是:统一日志框架,只保留一个 SLF4J 绑定器。
你需要从 Log4j2 和 Logback 中二选一,并排除所有冲突的依赖。从日志看,系统最终选择的是 Log4j2 ([org.apache.logging.slf4j.SLF4JServiceProvider]),因此建议移除 Logback 和冲突的 Log4j2 桥接包。
方案一:选择使用 Log4j2
如果你的项目是 Spring Boot 应用,并且想使用 Log4j2,可以按以下步骤操作:
排除 Spring Boot 默认的 Logback 依赖。
在 pom.xml 中,修改 spring-boot-starter 或 spring-boot-starter-web 的依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <!-- 排除默认的日志实现 Logback --> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency>
引入 Spring Boot 对 Log4j2 的官方支持 starter。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
这个 spring-boot-starter-log4j2 会自动为你引入正确且不冲突的 Log4j2 依赖(包括 log4j-core, log4j-api, log4j-slf4j2-impl),无需手动管理。
检查并移除其他可能引入冲突依赖的库。
运行 mvn dependency:tree 命令,查看是否还有其他依赖引入了 log4j-to-slf4j 或 logback-classic。如果有,在相应的依赖项中添加 标签将其排除。
