SAAJ-Impl 2.0.0与Jakarta兼容异常:JDK11测试时出现NoClassDefFoundError
咱们先拆解下你遇到的问题根源,主要是依赖版本不兼容加上JDK 11 对 Java EE 模块的移除导致的,具体来说:
核心问题点
版本冲突:Jakarta EE 9 与旧版 JAX-WS 不兼容
你引入的saaj-impl:2.0.0是 Jakarta EE 9 版本,它已经把包名从javax.xml.soap改成了jakarta.xml.soap,但你项目里用的jaxws-rt:2.3.3还是 Java EE 8 版本,依赖的是旧的javax.xml.soap包。两者包名不匹配,自然会导致初始化com.sun.xml.ws.api.SOAPVersion时找不到对应的依赖类。JDK 11 缺少必要的 Java EE 模块
JDK 8 自带了 JAX-WS、SAAJ 这类 Java EE 相关模块,但从 JDK 11 开始,Oracle 彻底移除了这些模块。所以你得手动引入完整的、版本匹配的 JAX-WS + SAAJ 依赖,而不是只补一部分。
具体解决方案
给你两个可行的方案,根据你的项目需求选:
方案一:保持 Java EE 8 版本栈(兼容现有代码)
如果不想改动代码里的包导入,就统一用和 jaxws-rt:2.3.3 匹配的 Java EE 8 版本依赖,替换掉你现在的 Jakarta 版本:
<!-- 替换Jakarta的SOAP API,用Java EE 8版本的SAAJ API --> <dependency> <groupId>javax.xml.soap</groupId> <artifactId>javax.xml.soap-api</artifactId> <version>1.4.0</version> </dependency> <!-- 用你之前JDK 8下能用的SAAJ实现,和jaxws-rt 2.3.3完美兼容 --> <dependency> <groupId>com.sun.xml.messaging.saaj</groupId> <artifactId>saaj-impl</artifactId> <version>1.5.3</version> </dependency> <!-- 补充JAX-WS API(JDK 11已移除,必须显式引入) --> <dependency> <groupId>javax.xml.ws</groupId> <artifactId>jaxws-api</artifactId> <version>2.3.3</version> </dependency>
另外注意:之前你把 jakarta.xml.soap-api 设为 test 作用域,这个必须去掉——运行测试时也需要加载这些API类,所以依赖不能局限在test环境。
方案二:升级到 Jakarta EE 9 版本栈(彻底迁移)
如果想跟进最新的Jakarta规范,就把所有相关依赖都换成Jakarta版本,同时修改代码里的包导入:
<!-- Jakarta EE 9版本的SOAP API --> <dependency> <groupId>jakarta.xml.soap</groupId> <artifactId>jakarta.xml.soap-api</artifactId> <version>2.0.0</version> </dependency> <!-- 对应版本的SAAJ实现 --> <dependency> <groupId>com.sun.xml.messaging.saaj</groupId> <artifactId>saaj-impl</artifactId> <version>2.0.0</version> </dependency> <!-- Jakarta EE 9版本的JAX-WS API --> <dependency> <groupId>jakarta.xml.ws</groupId> <artifactId>jakarta.xml.ws-api</artifactId> <version>3.0.0</version> </dependency> <!-- Jakarta EE 9版本的JAX-WS实现 --> <dependency> <groupId>com.sun.xml.ws</groupId> <artifactId>jaxws-rt</artifactId> <version>3.0.0</version> </dependency>
⚠️ 这个方案需要你把代码里的 import javax.xml.ws.*、import javax.xml.soap.* 全部改成 import jakarta.xml.ws.*、import jakarta.xml.soap.*,否则会编译报错。
额外提醒
检查项目里的其他依赖,有没有悄悄引入冲突的JAX-WS/SAAJ版本——比如某些第三方库可能自带旧版依赖,这时候需要用Maven的dependencyManagement统一版本,或者用<exclusions>排除掉冲突的依赖。
内容的提问来源于stack exchange,提问作者Nico S.

