Log4j1.x迁移2.x启动报NoClassDefFoundError:org/apache/log4j/Level
Log4j 1.x迁移Log4j 2.x启动报错问题排查
问题现象
将项目日志框架从Log4j 1.x迁移至Log4j 2.x,调整Maven依赖后启动应用,Spring上下文初始化阶段抛出异常,取消上下文刷新操作,无法启动bean org.springframework.jms.listener.DefaultMessageListenerContainer#0,嵌套异常为java.lang.NoClassDefFoundError: org/apache/log4j/Level,应用启动终止。
核心报错信息如下:
WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'org.springframework.jms.listener.DefaultMessageListenerContainer#0'; nested exception is java.lang.NoClassDefFoundError: org/apache/log4j/Level Jun 01, 2022 5:57:50 PM org.springframework.scheduling.concurrent.ExecutorConfigurationSupport shutdown INFO: Shutting down ExecutorService 'ucThreadPoolExecutor' [INFO ] [6458] 2022-06-01 17:57:50,767 [main] CacheManager-425 - Shutting down the executors on all the regions... [ERROR] [6459] 2022-06-01 17:57:50,768 [main] UnifiedCompareEngineApplication-52 - Failed to start bean 'org.springframework.jms.listener.DefaultMessageListenerContainer#0'; nested exception is java.lang.NoClassDefFoundError: org/apache/log4j/Level org.springframework.context.ApplicationContextException: Failed to start bean 'org.springframework.jms.listener.DefaultMessageListenerContainer#0'; nested exception is java.lang.NoClassDefFoundError: org/apache/log4j/Level at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:176) ~[com.XXXX1.0-SNAPSHOT.jar:?] at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51) ~[com.XXXX1.0-SNAPSHOT.jar:?] at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:346) ~[com.XXXX1.0-SNAPSHOT.jar:?] at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:149) ~[com.XXXX1.0-SNAPSHOT.jar:?] at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:112) ~[com.XXXX1.0-SNAPSHOT.jar:?] at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:852) ~[com.XXXX1.0-SNAPSHOT.jar:?] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541) ~[com.XXXX1.0-SNAPSHOT.jar:?] at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139) ~[com.XXXX1.0-SNAPSHOT.jar:?] at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83) ~[com.XXXX1.0-SNAPSHOT.jar:?]
问题根因
org.apache.log4j.Level是Log4j 1.x版本的专属类,Log4j 2.x的包路径为org.apache.logging.log4j,本身不包含Log4j 1.x的原生类。- 当前pom配置仅引入了
log4j-api、log4j-core两个Log4j2核心包,缺少Log4j 1.x到Log4j2的桥接依赖,项目中Spring JMS、其他第三方组件存在调用Log4j 1.x API的逻辑,找不到对应类就会抛出类不存在错误。 - 现有配置手动引入了低版本commons-logging依赖,同时注释掉了SLF4J相关依赖,没有做统一的日志路由,会进一步加剧日志绑定冲突问题。
修复方案
按照以下步骤调整pom.xml配置即可解决:
- 删除原有手动引入的commons-logging依赖
<!-- 删除这段配置 --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency>
- 补充Log4j2全量桥接依赖,将所有旧日志API的调用统一路由到Log4j2,版本和已引入的log4j-core、log4j-api保持一致为2.4.1:
<!-- 兼容Log4j 1.x API调用 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-1.2-api</artifactId> <version>2.4.1</version> </dependency> <!-- 兼容commons-logging(JCL) API调用 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-jcl</artifactId> <version>2.4.1</version> </dependency> <!-- 兼容SLF4J API调用 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.4.1</version> </dependency>
- 执行依赖排查命令,清理冲突包
执行mvn dependency:tree查看全量依赖树,如果存在传递引入的以下依赖,全部通过exclusion排除,避免日志绑定冲突:log4j:log4j(Log4j 1.x原生包)org.slf4j:slf4j-log4j12(SLF4J到Log4j1.x的实现包)commons-logging:commons-logging(原生commons-logging包)ch.qos.logback:logback-classic、ch.qos.logback:logback-core(Logback实现包)
- 重新打包验证
执行mvn clean package重新构建项目,原有shade插件配置的Log4j2插件缓存转换器可以正常生效,启动应用即可恢复正常。
内容的提问来源于stack exchange,提问作者PAA
相关产品推荐
相关产品推荐

