升级Struts至2.5.22后启动Tomcat遇log4j NoSuchMethodError求解决
这问题我之前帮同事排查过,核心原因就是你的log4j-api和log4j-core版本不匹配,直接导致了方法找不到的错误:你用的log4j-api是2.12.1,但log4j-core是2.13.2,而getStringProperty([Ljava/lang/String;Ljava/lang/String;Lorg/apache/logging/log4j/util/Supplier;)Ljava/lang/String;这个方法是在log4j-api 2.13.x版本才新增的,core 2.13.2调用了这个方法,但你的api版本太低,自然找不到它。
下面是具体的解决步骤:
统一log4j-api和log4j-core的版本
这是最关键的一步,log4j 2.x的api和core必须严格保持版本一致。推荐把log4j-api升级到和core相同的2.13.2版本(也可以把core降级到2.12.1,但更推荐升级api,因为高版本修复了更多安全和稳定性问题)。
如果用Maven,修改pom.xml的依赖配置:<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.13.2</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.13.2</version> </dependency>如果用Gradle,修改build.gradle:
implementation 'org.apache.logging.log4j:log4j-api:2.13.2' implementation 'org.apache.logging.log4j:log4j-core:2.13.2'排除Struts依赖中冲突的log4j版本
Struts 2.5.22本身可能依赖了特定版本的log4j,会和你手动引入的版本冲突。需要在Struts的依赖中排除自带的log4j模块,强制使用你指定的版本。以Maven为例:<dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.5.22</version> <exclusions> <exclusion> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> </exclusion> <exclusion> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> </exclusion> </exclusions> </dependency>清理依赖缓存并重新构建
执行项目构建工具的清理命令,确保旧的不兼容依赖被彻底移除:- Maven:
mvn clean install -U - Gradle:
clean build --refresh-dependencies
- Maven:
检查Tomcat容器的lib目录
有时候Tomcat的lib目录里会残留旧的log4j jar包,导致容器级别的依赖冲突。找到Tomcat安装目录下的lib文件夹,检查是否有log4j-api或log4j-core的旧版本jar,如果有就删除它们。
最后提醒一下:log4j 2.x的组件版本一致性非常重要,api、core以及其他相关组件(比如log4j-web)都要保持同一版本,否则很容易出现这类二进制兼容性问题。
内容的提问来源于stack exchange,提问作者Naeem Qayyum

