Java17升级后spring-ws-core 3.1.1出现SOAPDocumentImpl访问错误求助
问题
使用spring-ws-core 3.1.1时,原Java 11环境运行正常,升级到Java 17后调用外部SOAP服务报错。
调用代码:
customerRequestType = buildCustomerRequest(customerModel); ObjectFactory objectFactory = new ObjectFactory(); JAXBElement<CreateCustomerRequestType> jaxb = objectFactory.createCreateCustomerReques(customerRequestType); JAXBElement<CreateCustomerResponseType> responseJaxb = (JAXBElement<CreateCustomerResponseType>) customWebServiceTemplate.marshalSendAndReceive(jaxb); CreateCustomerResponseType customerResponse = responseJaxb.getValue();
Spring配置:
<bean id="customWebServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate"> <constructor-arg ref="clientMessageFactory" /> <property name="defaultUri" value="${vertex.service.create.customer.endpoint}" /> <property name="marshaller" ref="customerJaxbMarshaller" /> <property name="unmarshaller" ref="customerJaxbMarshaller" /> <property name="messageSender"> <bean class="org.springframework.ws.transport.http.HttpComponentsMessageSender"> <property name="connectionTimeout" value="5000" /> <property name="readTimeout" value="5000" /> </bean> </property> </bean>
错误日志核心信息:
"localizedMessage": "superclass access check failed: class com.sun.xml.messaging.saaj.soap.SOAPDocumentImpl (in unnamed module @0x7045bf72) cannot access class com.sun.org.apache.xerces.internal.dom.DocumentImpl (in module java.xml) because module java.xml does not export com.sun.org.apache.xerces.internal.dom to unnamed module @0x7045bf72"
补充错误细节:
Method threw 'java.lang.IllegalAccessError' exception. Cannot evaluate org.springframework.ws.soap.saaj.SaajSoapMessage.toString()
错误由MarshallingUtils.marshal方法触发,在构建SOAP请求时,MimeMessageContainer container = new MimeMessageContainer((MimeMessage)message)行引发问题。当前处于托管云环境,无法修改编译配置或传递JVM参数。
根因分析
这个问题是Java模块系统的访问限制导致的:
- Java 17对JDK内部API的访问限制比Java 11更严格,
com.sun.org.apache.xerces.internal.dom.DocumentImpl属于java.xml模块的内部类,JDK默认不允许未命名模块(比如老旧的SAJ库)访问这些内部API。 - Spring-WS依赖的
com.sun.xml.messaging.saaj库版本较旧,该库的SOAPDocumentImpl类继承了JDK内部的DocumentImpl,在Java 17的模块系统下触发了非法访问错误。
纠正措施
由于无法修改JVM参数,只能从依赖和配置层面入手:
1. 升级兼容Java 17的SAJ库
排除Spring-WS自带的旧版SAJ依赖,引入GlassFish Metro提供的兼容Java 17的SAJ实现。以Maven为例:
<dependency> <groupId>org.springframework.ws</groupId> <artifactId>spring-ws-core</artifactId> <version>3.1.1</version> <exclusions> <exclusion> <groupId>com.sun.xml.messaging.saaj</groupId> <artifactId>saaj-impl</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.glassfish.metro</groupId> <artifactId>webservices-saaj</artifactId> <version>4.0.2</version> <!-- 选择兼容Java17的版本 --> </dependency>
2. 升级Spring-WS到最新兼容版本
Spring-WS 3.1.x后续版本(如3.1.5+)已经修复了Java 17的兼容性问题,升级spring-ws-core版本可以直接解决该依赖冲突和模块访问问题。
3. 替换SOAP消息实现
如果无法升级依赖,可以将SaajSoapMessageFactory替换为AxiomSoapMessageFactory,绕过SAJ库的使用:
<bean id="clientMessageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory"> <property name="payloadCaching" value="true" /> </bean>
同时需要引入Axiom的依赖:
<dependency> <groupId>org.apache.ws.commons.axiom</groupId> <artifactId>axiom-api</artifactId> <version>1.4.0</version> </dependency> <dependency> <groupId>org.apache.ws.commons.axiom</groupId> <artifactId>axiom-impl</artifactId> <version>1.4.0</version> </dependency>
内容的提问来源于stack exchange,提问作者Umesh Awasthi
相关产品推荐
相关产品推荐

