在Digital Ocean部署Spring Boot WAR包到Tomcat时遇NoSuchMethodError问题咨询
问题根因
java.lang.NoSuchMethodError: org.springframework.util.StringUtils.matchesCharacter是典型的类版本冲突问题。
你项目基于Spring Boot 2.3.5.RELEASE开发,对应的Spring Framework 5.2.10版本里,StringUtils类是存在matchesCharacter(String, char)这个方法的。运行时抛错的核心原因是:Tomcat类加载机制优先加载自身公共lib目录下的类,加载到了版本更低的Spring核心Jar包,这个低版本Jar里的StringUtils根本没有上述方法,直接触发方法找不到的异常。
你当前配置里的直接触发点
- 错误给
spring-boot-starter-web配置了provided作用域。按照Maven依赖规则,provided范围的依赖不会被打进最终WAR包,会完全依赖运行环境提供对应Jar。这就意味着你的WAR包里根本没有把Spring Web、Spring Core这些核心类打进去,全靠Tomcat环境供给,如果环境里预置的是老版本Spring包,必然加载冲突。 - 部署时残留了旧的类加载缓存,没有清理Tomcat对应工作目录的应用临时文件,之前加载的冲突类没有被释放,新的WAR部署后还是会命中旧的低版本类。
可落地解决步骤
- 修正pom.xml的依赖配置:删掉
spring-boot-starter-web下的provided作用域,仅把容器提供的Servlet API单独设置为provided,修改后的对应依赖段参考:
<dependencies> <!-- 移除原spring-boot-starter-web下的<scope>provided</scope>配置 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 仅Servlet API设为provided,避免和Tomcat内置实现冲突 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <scope>provided</scope> </dependency> <!-- 其他原有依赖保持不变 --> </dependencies>
- 排查并清理Tomcat公共lib目录的冲突Jar:登录Digital Ocean上的服务器,找到Tomcat安装路径下的
lib文件夹,删除所有文件名带spring-*.jar的文件,让类加载器仅从当前应用的WEB-INF/lib目录加载Spring相关类,从根源阻断低版本包被优先加载的路径。 - 本地打包前校验依赖版本偏移:在项目本地执行命令
mvn dependency:tree | grep spring-core,确认输出的spring-core版本为5.2.10.RELEASE(和Spring Boot 2.3.5.RELEASE匹配),如果版本被其他依赖拉低,直接在pom的dependencyManagement节点锁定spring-core的版本即可。 - 清理Tomcat临时缓存后重新部署:删除Tomcat工作目录下对应你应用的临时文件夹(路径为
tomcat/work/Catalina/localhost/你的应用上下文名),再执行mvn clean package生成新的WAR包,替换掉Tomcat webapps目录下的旧应用文件,重启Tomcat即可生效。
内容的提问来源于stack exchange,提问作者smul.hn
相关产品推荐
相关产品推荐

