JDK17下带main方法的JAX-WS客户端调用WildFly27服务失败
JAX-WS客户端调用WildFly 27服务时Provider类转换异常排查
问题背景
使用Corretto JDK17、Maven构建的Java客户端,调用WildFly v27上运行的JAX-WS Web服务时,始终抛出jakarta.xml.ws.spi.Provider相关的类转换异常。已知现象:
- 客户端Maven构建无编译错误,JAR内容符合预期
- WSDL URL可正常访问,调试时能进入
jakarta.xml.ws.Service构造方法,但后续抛出异常 - 确认是运行时类路径冲突问题,调整pom.xml后仍未解决
核心错误分析
从堆栈信息中的关键异常:
java.lang.ClassCastException: class com.sun.xml.ws.spi.ProviderImpl cannot be cast to class jakarta.xml.ws.spi.Provider
可以明确问题根源:
- 类路径中同时存在Jakarta EE版本的JAX-WS API(
jakarta.xml.ws.*包)和旧JEE版本的JAX-WS实现(基于javax.xml.ws.*包的com.sun.xml.ws2.x系列) - 旧实现类
com.sun.xml.ws.spi.ProviderImpl实现的是javax.xml.ws.spi.Provider,而当前代码依赖的是jakarta.xml.ws.spi.Provider,两者属于不同命名空间,无法进行类型转换
解决方案
1. 清理并重构pom.xml依赖
删除所有冲突的旧版本依赖,统一使用Jakarta EE兼容的JAX-WS依赖:
- 移除所有
javax.xml.ws相关依赖(如jaxws-api:2.3.1) - 移除旧版本
com.sun.xml.ws依赖(jaxws-rt:2.3.3、jaxws-ri:2.3.3、rt:2.3.2) - 添加Jakarta版本的JAX-WS RI实现(版本需与Jakarta API版本匹配,比如4.0.0对应Jakarta EE 10)
- 统一API依赖,保留一个Jakarta XML WS API即可
- 将编译版本调整为17(匹配使用的JDK17)
修正后的pom.xml示例:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>JAXWS_Client-NEW</artifactId> <version>1.0-SNAPSHOT</version> <name>JAXWS_Client-NEW</name> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.target>17</maven.compiler.target> <maven.compiler.source>17</maven.compiler.source> <jakarta.xml.ws.version>4.0.0</jakarta.xml.ws.version> <jakarta.xml.bind.version>4.0.0</jakarta.xml.bind.version> <log4j.version>2.20.0</log4j.version> </properties> <dependencies> <!-- Log4j 依赖 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-to-slf4j</artifactId> <version>${log4j.version}</version> </dependency> <!-- Jakarta XML Binding API --> <dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> <version>${jakarta.xml.bind.version}</version> </dependency> <!-- JAXB 实现 --> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>${jakarta.xml.bind.version}</version> <scope>runtime</scope> </dependency> <!-- Jakarta XML WS API --> <dependency> <groupId>jakarta.xml.ws</groupId> <artifactId>jakarta.xml.ws-api</artifactId> <version>${jakarta.xml.ws.version}</version> </dependency> <!-- Jakarta 版本的 JAX-WS RI 实现 --> <dependency> <groupId>com.sun.xml.ws</groupId> <artifactId>jaxws-rt</artifactId> <version>${jakarta.xml.ws.version}</version> <type>pom</type> </dependency> <!-- Jakarta SOAP API --> <dependency> <groupId>jakarta.xml.soap</groupId> <artifactId>jakarta.xml.soap-api</artifactId> <version>3.0.0</version> </dependency> </dependencies> </project>
2. 修正客户端代码中的QName错误
原代码中QName的参数使用了URL,这是错误的,应该使用WSDL中的targetNamespace和服务的本地名称:
// 修正前错误的QName // QName qName = new QName("http://localhost:8080/employee-service/EmployeeService"); // 修正后:targetNamespace从WSDL中获取,本地名称为服务名 QName qName = new QName("http://ws.jaxws.example.com/", "EmployeeService");
验证步骤
- 执行
mvn clean package重新构建客户端 - 运行客户端JAR,确认异常消失,能够正常调用WildFly上的Web服务
内容的提问来源于stack exchange,提问作者mcs130
相关产品推荐
相关产品推荐

