I’m trying to generate Java classes from the FpML (Finanial Products Markup Language) version 4.5. A ton of code is generated, but I cannot use it. Trying to serialize a simple document I get this:
javax.xml.bind.MarshalException
- with linked exception: [com.sun.istack.SAXException2: unable
to marshal type
"org.fpml._2008.fpml_4_5.PositionReport"
as an element because it is missing an
@XmlRootElement annotation]
In fact no classses have the @XmlRootElement annotation, so what can I be doing wrong?. I’m pointing xjc (JAXB 2.1) to fpml-main-4-5.xsd, which then includes all types.
To tie together what others have already stated or hinted at, the rules by which JAXB XJC decides whether or not to put the
@XmlRootElementannotation on a generated class are non trivial (see this article).@XmlRootElementexists because the JAXB runtime requires certain information in order to marshal/unmarshal a given object, specifically the XML element name and namespace. You can’t just pass any old object to the Marshaller.@XmlRootElementprovides this information.The annotation is just a convenience, however – JAXB does not require it. The alternative to is to use
JAXBElementwrapper objects, which provide the same information as@XmlRootElement, but in the form of an object, rather than an annotation.However,
JAXBElementobjects are awkward to construct, since you need to know the XML element name and namespace, which business logic usually doesn’t.Thankfully, when XJC generates a class model, it also generates a class called
ObjectFactory. This is partly there for backwards compatibility with JAXB v1, but it’s also there as a place for XJC to put generated factory methods which createJAXBElementwrappers around your own objects. It handles the XML name and namespace for you, so you don’t need to worry about it. You just need to look through theObjectFactorymethods (and for large schema, there can be hundreds of them) to find the one you need.