You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级Log4j v2.17.2出现RuntimeStrSubstitutor类初始化失败报错

问题根因

首先明确:java.lang.NoClassDefFoundError: Could not initialize class org.apache.logging.log4j.core.lookup.RuntimeStrSubstitutor 不是指该类文件缺失,而是 类的静态初始化代码块执行时抛出未捕获异常,JVM将该类标记为初始化失败,后续所有访问该类的操作都会直接抛出该错误。

Log4j 2.17.2版本对RuntimeStrSubstitutor的静态初始化逻辑做了调整,新增了对全局lookup实例、字符串转义工具类的静态加载,触发该问题的核心原因基本可以归为三类:

  • 类路径下存在多版本Log4j组件混装:比如log4j-api升级到了2.17.2,但log4j-core、log4j-to-slf4j等相关组件还是2.17.1甚至更低版本,或者第三方依赖传递进来了旧版Log4j组件。2.17.2版本的RuntimeStrSubstitutor初始化时会调用2.17.2才新增的lookup相关方法,旧版本类中没有对应方法,直接抛异常导致类初始化失败。
  • 存在不兼容的Log4j桥接/第三方插件包:比如项目引入了和2.17.2版本不匹配的slf4j桥接包,或者老版本Spring Boot、Shiro、Dubbo等第三方组件自带的Log4j插件未同步升级,初始化时注入lookup逻辑失败,触发静态块报错。
  • 打包配置错误:使用maven-shade-plugin等重打包插件时,没有配置Log4j的SPI资源文件合并规则,导致META-INF/services下的StrLookup配置被覆盖,RuntimeStrSubstitutor初始化加载内置lookup时找不到默认实现,触发报错。
排查思路

按优先级从高到低排查即可:

  1. 全量排查Log4j相关依赖版本
    执行命令mvn dependency:tree -Dincludes=org.apache.logging.log4j:* -Dverbose,注意不要遗漏test作用域的依赖(当前报错在JUnit测试阶段触发,test范围的包会进入测试类路径),检查所有groupId为org.apache.logging.log4j的组件(包括log4j-api、log4j-core、log4j-to-slf4j、log4j-slf4j-impl等),确认所有包版本统一为2.17.2,无旧版本被传递引入。
  2. 打印类初始化原始异常
    给单元测试添加JVM启动参数-XX:+TraceClassInitialization,重新执行测试,控制台会打印RuntimeStrSubstitutor类初始化时抛出的原始异常栈(通常是NoSuchMethodError、ClassNotFoundException这类),顺着原始栈可以直接定位到具体冲突的类。
  3. 检查打包插件配置
    如果模块单独测试正常、打出来的包运行报错,检查maven-shade-plugin、spring-boot-maven-plugin等重打包插件的配置,确认是否配置了资源合并规则处理Log4j的SPI配置文件。
  4. 排查自定义Log4j插件
    检查项目内是否存在自定义的StrLookup实现,或者通过@Plugin注解注册的自定义Log4j插件,确认插件代码兼容2.17.2版本的类逻辑。
解决方案

对应排查结果处理即可:

  1. 统一所有Log4j组件版本
    如果存在传递依赖引入的旧版本Log4j包,在对应依赖上添加exclusion排除旧版本,更稳妥的方式是在pom的dependencyManagement中导入Log4j官方BOM,强制统一所有Log4j组件版本,从根源避免版本不一致问题:
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-bom</artifactId>
                <version>2.17.2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
    导入BOM后,所有Log4j组件不需要再单独指定version,会自动对齐到2.17.2版本。
  2. 升级不兼容的第三方依赖
    如果是第三方组件自带的Log4j插件不兼容,找到对应依赖升级到适配Log4j 2.17.2的版本;如果是slf4j相关桥接包版本不匹配,将slf4j-api、桥接包版本和Log4j版本对齐即可。
  3. 修复打包插件配置
    如果使用maven-shade-plugin打包,添加SPI资源合并的transformer配置,避免服务配置被覆盖:
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.4.1</version>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>shade</goal>
                </goals>
                <configuration>
                    <transformers>
                        <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                        <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"/>
                    </transformers>
                </configuration>
            </execution>
        </executions>
    </plugin>
    
  4. 临时兼容方案
    如果暂时无法定位冲突点,可以直接升级到Log4j 2.17.3版本,该版本对RuntimeStrSubstitutor的初始化逻辑做了容错处理,不会因为单个lookup加载失败导致整个类初始化失败,兼容性远好于2.17.2版本。
补充说明

Log4j 2.17.2是为修复CVE-2021-44832漏洞发布的小版本,本身没有对外API的破坏性变更,其发布说明中明确要求所有Log4j核心组件必须保持版本一致,混装版本不在兼容支持范围内。正常全量升级所有Log4j相关包的场景下不会出现该报错,99%的案例都是类路径下混装不同版本Log4j组件导致的。

内容的提问来源于stack exchange,提问作者link716

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 07:27:17