Spring 4.0.1.RELEASE升级至5.0.6.RELEASE出现NoSuchMethodError求助
我正尝试将Spring 4.0.1.RELEASE升级到最新版本5.0.6.RELEASE,修改pom.xml中的版本后出现如下错误:
org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/spring/appServlet/servlet-context.xml]; nested exception is java.lang.NoSuchMethodError: org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.getEnvironment()Lorg/springframework/core/env/Environment;
该项目在Spring 4.0.1.RELEASE版本下可正常运行。
我的pom.xml配置如下:
<properties> <java-version>1.8</java-version> <org.springframework-version>5.0.6.RELEASE</org.springframework-version> <org.aspectj-version>1.6.10</org.aspectj-version> <org.slf4j-version>1.6.6</org.slf4j-version> </properties> <dependencies> <!-- Spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${org.springframework-version}</version> <exclusions> <!-- Exclude Commons Logging in favor of SLF4j --> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${org.springframework-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${org.springframework-version}</version> </dependency> <!-- Joda TIme dependency for date and time --> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.3</version> </dependency> <!-- Spring security --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>3.1.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>3.1.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>3.1.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-taglibs</artifactId> <version>3.1.3.RELEASE</version> </dependency> </dependencies>
servletContext.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:c='http://www.springframework.org/schema/c' xmlns:mongo="http://www.springframework.org/schema/data/mongo" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:ldap="http://www.springframework.org/schema/ldap" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd http://www.springframework.org/schema/ldap http://www.springframework.org/schema/ldap/spring-ldap.xsd"> <context:component-scan base-package="com.abc.xyz" /> </beans:beans>
请问我遗漏了什么配置或步骤?
问题原因分析
这个错误的核心是Spring Security版本和你升级后的Spring 5.x完全不兼容。你用的Spring Security 3.1.3.RELEASE是2013年的老版本,它依赖的是Spring 3.x的API;而Spring 5.x对BeanDefinitionParserDelegate类做了修改,新增了getEnvironment()方法,旧版Spring Security代码调用这个类时找不到该方法,直接抛出NoSuchMethodError。
另外还有两个潜在的版本不兼容点:
- AspectJ 1.6.10版本太老,Spring 5.x建议用AspectJ 1.8.x及以上
- SLF4J 1.6.6版本也偏旧,升级到1.7.x或更高版本能更好兼容Spring 5的日志体系
解决方案
1. 升级Spring Security到兼容Spring 5.x的版本
Spring 5.0.x对应的兼容Spring Security版本是4.2.x.RELEASE(Spring Security 5.0.x需要Spring 5.1+,所以不能直接用)。把所有Spring Security依赖的版本统一改成4.2.13.RELEASE(这是4.2系列的最后一个稳定版):
<!-- Spring security --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>4.2.13.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>4.2.13.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>4.2.13.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-taglibs</artifactId> <version>4.2.13.RELEASE</version> </dependency>
2. 升级AspectJ和SLF4J版本
修改properties里的版本号:
<properties> <java-version>1.8</java-version> <org.springframework-version>5.0.6.RELEASE</org.springframework-version> <org.aspectj-version>1.8.13</org.aspectj-version> <!-- 升级到兼容Spring 5的版本 --> <org.slf4j-version>1.7.36</org.slf4j-version> <!-- 升级到稳定新版本 --> </properties>
3. 清理依赖并重新构建
改完pom.xml后,执行Maven命令清理旧依赖并重新构建,确保所有依赖都是最新且兼容的:
mvn clean install
4. 检查XML配置的schema版本(可选)
虽然你的servlet-context.xml目前没问题,但建议确认所有Spring相关的schema版本是否匹配Spring 5.x。不过你当前配置的schema地址是动态的,通常会自动匹配版本,这一步可以作为额外验证。
验证
完成上述修改后重启项目,应该就能解决NoSuchMethodError问题。如果还有其他错误,可能是其他第三方依赖和Spring 5.x不兼容,建议逐一排查升级。
内容的提问来源于stack exchange,提问作者Prashant Thorat

