Log4j v1迁移至Log4j2时SLF4JLoggerContextFactory初始化失败问题
解决Spring Integration迁移Log4j1到Log4j2后的初始化错误
问题根源
报错ERROR StatusLogger LogManager returned an instance of org.apache.logging.slf4j.SLF4JLoggerContextFactory which does not implement org.apache.logging.log4j.core.impl.Log4jContextFactory的核心原因:
- 类路径中存在SLF4J与Log4j2的桥接依赖冲突,导致错误加载了SLF4J的上下文工厂,而非Log4j2核心的工厂类
- 你添加的
log4j-to-slf4j是反向桥接组件(将Log4j2日志转发到SLF4J),这会加剧冲突,无法解决问题
解决方案
1. 修正依赖配置(关键步骤)
移除log4j-to-slf4j依赖,替换为SLF4J绑定Log4j2的实现包,统一所有Log4j2组件版本,并排除冲突依赖:
<!-- Log4j2 核心依赖,统一使用稳定版本 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.20.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.20.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-web</artifactId> <version>2.20.0</version> <scope>runtime</scope> </dependency> <!-- SLF4J 绑定到 Log4j2(替代旧的 slf4j-log4j12) --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.20.0</version> </dependency> <!-- 排除Spring Integration中的冲突日志依赖 --> <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-core</artifactId> <exclusions> <!-- 排除旧的Log4j1桥接包 --> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> <!-- 排除commons-logging,统一用SLF4J --> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency>
2. 调整Web.xml配置
确保Log4j2的监听器优先加载,配置文件参数正确:
<!-- Log4j2 配置文件路径 --> <context-param> <param-name>log4jConfiguration</param-name> <param-value>file:///opt/ds-log4j2.properties</param-value> </context-param> <!-- Log4j2 监听器必须在Spring监听器之前加载 --> <listener> <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class> </listener>
3. 验证配置文件格式
Log4j2的properties格式与Log4j1差异较大,示例配置如下:
status = warn name = PropertiesConfig # 控制台输出配置 appender.console.type = Console appender.console.name = STDOUT appender.console.layout.type = PatternLayout appender.console.layout.pattern = %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n # 根日志级别配置 rootLogger.level = info rootLogger.appenderRefs = stdout rootLogger.appenderRef.stdout.ref = STDOUT
4. 排查类路径冲突
用Maven命令检查依赖树,确认无残留冲突依赖:
mvn dependency:tree | grep -E "(log4j1|slf4j-log4j12|log4j-to-slf4j)"
若输出存在上述依赖,在对应<dependency>中添加<exclusion>排除。
内容的提问来源于stack exchange,提问作者Naveen Naduvinamani
相关产品推荐
相关产品推荐

