我正在将项目从版本 1.x 升级到 jaxb 2.2.7。
我的应用程序有时可以运行,但在一些回复中我看到了这一点:
java.lang.RuntimeException: javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.SAXException2: Instance of "com.mycompany.global.er.decoupling.binding.response.PricePointType$BalanceImpactRates$BalanceImpactRate"
is substituting "java.lang.Object", but
"com.mycompany.global.er.decoupling.binding.response.PricePointType$BalanceImpactRates$BalanceImpactRate"
is bound to an anonymous type.]
这在 jaxb 1.0 中运行良好。我不知道问题是什么。
这是 xsd 的摘录(我无法更改,因为客户正在使用它):
<xs:complexType name="price-pointType">
<xs:sequence>
<xs:element name="id" type="xs:string" />
.........
<xs:element name="duration" type="durationType" />
<xs:element name="order" type="xs:int" />
<xs:element name="min-sub-period" type="xs:int" />
<xs:element name="balance-impacts" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="balance-impact" type="charging-resourceType"
minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="balance-impact-rates" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="balance-impact-rate" minOccurs="0"
maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="rate" type="xs:double" />
</xs:sequence>
<xs:attribute name="charging-resource-code" type="xs:string"
use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
有什么建议吗?
问题原来是匿名复杂类型的精心嵌套。
通过如下所示将它们分开,问题就消失了。作为额外的好处,我获得了更多可重用的代码。
<xs:complexType name="balanceImpactRate">
<xs:sequence>
<xs:element name="rate" type="xs:double" />
</xs:sequence>
<xs:attribute name="charging-resource-code" type="xs:string"
use="required" />
</xs:complexType>
<xs:complexType name="balanceImpactRates" >
<xs:sequence>
<xs:element name="balance-impact-rate" type="balanceImpactRate" minOccurs="0"
maxOccurs="unbounded">
</xs:element>
</xs:sequence>
</xs:complexType>
在尝试编组从 hibernate-mapping-4.0.xsd 生成的一些 jaxb 对象时,我遇到了同样的异常
抛出的异常似乎涉及作为 HibernateMapping 根类的内部类生成的两个类 - “Id”和“CompositeID”。这两个元素在 XSD 中定义为嵌套的复杂类型,就像 @mdarwin 的情况一样。通过将复杂类型定义移出(以便它们成为 xsd 中“schema”元素的根元素),问题就得到了解决,对象也被成功封送。
遗憾的是,我本来希望使用未修改的 XSD 来生成我的 jaxb 对象 - 但找不到解决该问题的另一种方法。
我注意到的情况不依赖于 xsd-schema 中的
<xs:complexType>
定义。
实际的问题是我们的 Java 类是从 xml 模式生成的类扩展的。
这些类用
@XmlType(name = "")
进行注释,使它们匿名(即生成的标签不包含 xsi:type
属性,并且生成的 xml 文件对于初始模式仍然有效。
我在 java、xsd & marshalling: jre bug、我的错还是 xsd 问题?中找到了此解决方案的线索。
由于我无法修改xsd(它太复杂并且已经共享给我们API的客户端),解决方案是:
创建一个 jaxb-binder,排除要生成到 Java 文件中的复杂类型,并指示 JAXB 使用现有的类。 绑定文件如下所示:
<jxb:bindings schemaLocation="MySchema.xsd">
<jxb:bindings node="//xs:complexType[@name='TheClassYouWantToExclude']">
<jxb:class ref="my.existing.class.TheClassYouWantToExclude"/>
</jxb:bindings>
</jxb:bindings>
在现有的类中,我们需要扩展的类不是JAXB注释的类,只是一个抽象类:
package my.existing.class;
public abstract class TheClassFromWhichYouWantToExtend {
}
@XmlAnyElement(lax = true)
注释:
package my.existing.class;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(...)
public class TheClassYouWantToExclude {
// ...
@XmlAnyElement(lax = true)
protected TheClassFromWhichYouWantToExtend theClassFromWhichYouWantToExtend;
}
就我而言,解决方案有所不同。 我有一个 dtd 来生成 java 类。其中的定义之一如下
((Adults, Children?, Infants?, RoomType?) | RoomConfigs)
所以生成的java方法是
getAdultsOrChildrenOrInfantsOrRoomTypeOrRoomConfigs().add(object)
object 应该是 RoomConfigs 或 Adults ecc 的实例...但我添加了 RoomConfig 的实例,这是一个稍微不同的类。 因此,当您遇到此错误时,请确保添加正确类的实例。