Apache Ignite使用WebFlux初始化WebClient报NoSuchMethodError
问题根因
这个java.lang.NoSuchMethodError是典型的类路径Jar包版本冲突问题,初步排查方向完全正确:
org.springframework.util.xml.StaxUtils.createDefensiveInputFactory()是Spring Core 5.0及以上版本才新增的方法,Spring 4.x分支中不存在该方法- 仅在Linux环境复现是类加载顺序差异导致:Linux环境下JVM加载类路径资源时,优先加载到了Apache Ignite内置的Spring 4.3.26.RELEASE版本的类;Windows环境类加载顺序不同,优先读取到项目引入的Spring 5版本类,因此不会触发异常,和业务代码逻辑无关。
解决方案
按落地成本从低到高、彻底性从高到低排序:
- 统一Spring版本(推荐首选)
Apache Ignite 2.8及以上版本原生兼容Spring 5,直接在依赖配置中排除Ignite所有内置的Spring 4.x相关包,全局统一使用和WebFlux匹配的Spring 5版本即可。
Maven项目排除示例:
对所有引入的Ignite相关组件(比如ignite-spring、ignite-web等)都做同样的排除操作,之后在项目依赖中明确指定所有Spring相关包的版本,和WebFlux依赖的Spring版本保持完全一致即可。<dependency> <groupId>org.apache.ignite</groupId> <artifactId>ignite-core</artifactId> <version>你当前使用的Ignite版本</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency> - 调整类加载优先级
如果你使用的Ignite版本低于2.8,无法直接兼容Spring 5,可以通过调整类路径顺序保证Spring 5的Jar包优先被加载:- 若使用Spring Boot打包,在maven打包插件中配置资源优先级,将项目引入的Spring 5相关Jar排在类路径最前端
- 若直接通过脚本启动,在
java命令的-cp参数中,把Spring 5相关Jar的路径写在Ignite依赖Jar的前面,Linux环境下类路径按书写顺序从前到后加载,排在前面的类会优先被加载,不会读取到后面的旧版本类
- 类加载器隔离
如果以上两种方案都无法落地(比如Ignite版本过低且无法升级,和Spring 5存在兼容性问题),可以将WebClient相关的逻辑独立拆分,使用自定义类加载器单独加载Spring 5及WebFlux相关的类,和Ignite自带的Spring 4环境做隔离,该方案实现成本较高,仅作为兜底选项。
验证方法
调整配置后,启动时添加JVM参数-verbose:class,观察日志中org.springframework.util.xml.StaxUtils类的加载来源,如果是从你引入的Spring 5版本Jar包中加载,异常即可消除。
内容的提问来源于stack exchange,提问作者Maxim Volkomorov
相关产品推荐
相关产品推荐

