Java8转Java21后WebService JAXB反序列化异常求助
问题背景
近期将WebService从Java8迁移至Java21、Spring6及SpringBoot3,已完成所有javax.xml.bind到jakarta.xml.bind的替换,并升级了JAXB、JAXWS的最新依赖。迁移后部分原有请求无法正常处理,服务无法反序列化请求,报错jakarta.xml.bind.UnmarshalException: Unable to create an instance of com.cie.cdo.contract.impl.AbstractContract。生成XSD的WSDL未发生变化,仅部分请求出现该问题。已尝试为AbstractContract添加@XmlTransient、移除抽象修饰等方案,但均无效。
异常信息
异常堆栈片段
jakarta.xml.bind.UnmarshalException: Unable to create an instance of com.cie.cdo.contract.impl.AbstractContract at org.glassfish.jaxb.runtime.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:701) ~[jaxb-impl-3.0.2.jar:3.0.2] ...
完整异常堆栈
jakarta.xml.bind.UnmarshalException: Unable to create an instance of com.cie.cdo.contract.impl.AbstractContract at org.glassfish.jaxb.runtime.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:701) ~[jaxb-impl-3.0.2.jar:3.0.2] ... Caused by: java.lang.InstantiationException at java.base/jdk.internal.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48) ~[?:?] ...
核心依赖版本
<jakarta-xml-bind-api.version>4.0.2</jakarta-xml-bind-api.version> <jaxb-impl.version>3.0.2</jaxb-impl.version> <jaxws-rt.version>4.0.3</jaxws-rt.version> ...
相关代码片段
AbstractContract类
package com.cbo.contract.impl; import jakarta.xml.bind.annotation.*; public abstract class AbstractContract extends BusinessObject { private static final long serialVersionUID = 1836923300872990415L; }
问题请求SOAP XML
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header/> <soapenv:Body> <nsdcs:CreateDocumentRequest ...> ... </nsdcs:CreateDocumentRequest> </soapenv:Body> </soapenv:Envelope>
排查与解决方案建议
补全JAXB继承映射配置
抽象类AbstractContract作为父类,必须通过@XmlSeeAlso声明所有子类,让JAXB在反序列化时识别具体实现类。示例:@XmlSeeAlso({ConcreteContractA.class, ConcreteContractB.class}) public abstract class AbstractContract extends BusinessObject { // 原有代码 }若缺失该注解,JAXB无法知晓抽象类的具体实现,会直接尝试实例化抽象类导致异常。
验证SOAP请求的类型标识
检查问题请求中是否包含xsi:type属性指定具体子类,比如契约元素应类似:<contract xsi:type="nsdcs:ConcreteContract" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <!-- 元素内容 --> </contract>若请求缺失该标识,JAXB会默认尝试实例化父类(抽象类),触发实例化异常。
对齐JAXB依赖版本
当前jakarta-xml-bind-api:4.0.2与jaxb-impl:3.0.2版本不匹配,API 4.x对应实现应为4.x版本。统一升级依赖:<jakarta-xml-bind-api.version>4.0.2</jakarta-xml-bind-api.version> <jaxb-impl.version>4.0.2</jaxb-impl.version> <jaxws-rt.version>4.0.3</jaxws-rt.version>版本不匹配可能导致JAXB内部逻辑异常,影响类型映射处理。
检查SpringBoot JAX-WS配置
SpringBoot3对JAX-WS的自动配置有变化,需确保jaxws-spring-boot-starter等依赖正确引入,且配置类中正确声明JAX-WS端点,避免上下文初始化时遗漏子类的JAXB映射注册。
内容的提问来源于stack exchange,提问作者Chris

