问题
I'm upgrading a project to jaxb 2.2.7 from version 1.x.
I've got the app working some of the time, but on some responses I see this:
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.]
This worked fine in jaxb 1.0. I've no idea what the problem could be.
Here's an extract from the xsd (which I can't change, since clients are using it):
<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>
Any suggestions?
回答1:
The problem turned out to be the elaborate nesting of anonymous complex types.
By separating them out as below, the problem went away. And as an added bonus, I got more re-usable code.
<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>
回答2:
I got the same exception when attempting to marshal some jaxb obejcts that I had generated from the hibernate-mapping-4.0.xsd
The exceptions that were being thrown seemed to involve two classes that were generated as inner classes of the class HibernateMapping root class - "Id" and "CompositeID". Both of these elements were defined in the XSD as nested complexTypes, just as in @mdarwin's case. By moving the complexType definitions out (so that they were root elements of the "schema" element in the xsd) then the problem was resolved and the objects were successfully marshaled.
A shame as I would have liked to have used the unmodified XSD to generate my jaxb object - but could not find another way around the problem.
回答3:
The case that I noted does not depend on <xs:complexType>
definitions in xsd-schema.
The actual problem was that we have Java classes that extend from a class generated from xml-schema.
And these classes are annotated with @XmlType(name = "")
to make them anonymous (i.e. that generated tag does not contain xsi:type
attribute and the generated xml-file remains valid for the initial-schema.
I found the clue to this solution in java, xsd & marshalling: jre bug, my fault or xsd issues?.
Since I can't modify the xsd (it is too complex and is already shared to the clients of our APIs), the solution is:
Make a jaxb-binder that excludes the complexType to be generated into Java file and says JAXB to use the existing class instead. Binding file looks like this:
<jxb:bindings schemaLocation="MySchema.xsd"> <jxb:bindings node="//xs:complexType[@name='TheClassYouWantToExclude']"> <jxb:class ref="my.existing.class.TheClassYouWantToExclude"/> </jxb:bindings> </jxb:bindings>
In existing class, the class that we need to extend is NOT a JAXB-annotated class, just an abstract class:
package my.existing.class;
public abstract class TheClassFromWhichYouWantToExtend {
}
- The field that links to this class from the parent class is annotated with
@XmlAnyElement(lax = true)
:
package my.existing.class;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(...)
public class TheClassYouWantToExclude {
// ...
@XmlAnyElement(lax = true)
protected TheClassFromWhichYouWantToExtend theClassFromWhichYouWantToExtend;
}
来源:https://stackoverflow.com/questions/21117879/com-sun-istack-saxexception2-instance-is-substituting-java-lang-object