Unable to marshal type as XML element because @XmlRootElement annotation is missing
Solution 1
public String toXML(T object) throws JAXBException {
StringWriter stringWriter = new StringWriter();
JAXBContext jaxbContext = JAXBContext.newInstance(T.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// format the XML output
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
QName qName = new QName("com.yourModel.t", "object");
JAXBElement<T> root = new JAXBElement<Bbb>(qName, T.class, object);
jaxbMarshaller.marshal(root, stringWriter);
String result = stringWriter.toString();
LOGGER.info(result);
return result;
}
Here is the article I use when I have to marshal/unmarshal without @XmlRootElement: http://www.source4code.info/2013/07/jaxb-marshal-unmarshal-with-missing.html
All the best hope it helps :)
Solution 2
Note that the error message talks about FreightOfferDetail
, not FreightOffer
.
Based on that, I would expect that somewhere (outside the provided code), you're asking a Detail to be marshalled.
If you want to be able to do that (with JAXB?) you need to annotate that class as well with the XmlRootElement annotation.
Solution 3
You can use the ObjectFactory class to workaround for the classes which doesn't have the @XmlRootElement. ObjectFactory has overloaded methods.
Method:1 It does simple creation of the object and
Method:2 It will wrap the object with @JAXBElement.
Always to use Method:2 to avoid javax.xml.bind.MarshalException - with linked exception missing an @XmlRootElement annotation
Method:1
public GetCountry createGetCountry() {
return new GetCountry();
}
Method:2
@XmlElementDecl(namespace = "my/name/space", name = "getCountry")
public JAXBElement<GetCountry> createGetCountry(GetCountry value) {
return new JAXBElement<GetCountry>(_GetCountry_QNAME, GetCountry.class, null, value);
}
for more information follow this stackoverflow-question
Hope this will be helpful...
catch23
Updated on July 05, 2022Comments
-
catch23 almost 2 years
I want to marshal object to XML.
However, it fails with exception:
javax.xml.bind.MarshalException - with linked exception: [com.sun.istack.SAXException2: unable to marshal type "FreightOfferDetail" as an element because it is missing an @XmlRootElement annotation] at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:331) at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:257) at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:96) at com.wktransportservices.fx.test.util.jaxb.xmltransformer.ObjectTransformer.toXML(ObjectTransformer.java:27) at com.wktransportservices.fx.test.sampler.webservice.connect.FreightOfferToConnectFreight.runTest(FreightOfferToConnectFreight.java:59) at org.apache.jmeter.protocol.java.sampler.JavaSampler.sample(JavaSampler.java:191) at org.apache.jmeter.threads.JMeterThread.process_sampler(JMeterThread.java:429) at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:257) at java.lang.Thread.run(Thread.java:662) Caused by: com.sun.istack.SAXException2: unable to marshal type "FreightOfferDetail" as an element because it is missing an @XmlRootElement annotation at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:244) at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:303) at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:490) at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:328)
In fact, this annotation is present (for parent and delivered class):
@XmlRootElement(name = "Freight_Offer") @XmlAccessorType(XmlAccessType.FIELD) @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_EMPTY) public class FreightOffer { @JsonIgnore @XmlTransient private String freightId; private String id; private String externalSystemId; private AddressLocation pickUp; private AddressLocation delivery; private FreightDescription freightDescription; private ListContacts contacts; private Customer customer; private ListSla slas; private String pushId; private CompanyProfile company; private Route route; private String href; private Lifecycle lifecycle; private Visibility visibility; private Boolean unfoldedVXMatching; // getters / setters
Child class:
@XmlAccessorType(XmlAccessType.PROPERTY) public class FreightOfferDetail extends FreightOffer { private List<Contact> contact; @XmlElement(name = "contacts") @JsonProperty("contacts") public List<Contact> getContact() { return contact; } public void setContact(List<Contact> contact) { this.contact = contact; }
It fails exactly at this method
toXML()
:public class ObjectTransformer<T> implements Transformer<T> { protected final JAXBContext context; protected final Marshaller marshaller; protected final int okStatusCode = 200; protected final String okSubErrorCode = "OK"; public ObjectTransformer(JAXBContext context) throws JAXBException { this.context = context; marshaller = context.createMarshaller(); marshaller.setProperty("jaxb.encoding", "UTF-8"); marshaller.setProperty("jaxb.formatted.output", Boolean.TRUE); } public String toXML(T object) throws JAXBException { StringWriter writer = new StringWriter(); marshaller.marshal(object, writer); String xmlOffer = writer.toString(); return xmlOffer; }
It should work, but it shouldn't.
I couldn't find what is missed or wrong here.
UPDATE:
Here is snippet from test:
public SampleResult runTest(JavaSamplerContext context) { AbstractSamplerResults results = new XMLSamplerResults(new SampleResult()); results.startAndPauseSampler(); if (failureCause != null) { results.setExceptionFailure("FAILED TO INSTANTIATE connectTransformer", failureCause); } else { FreightOfferDTO offer = null; FreightOffer freightOffer = null; try { results.resumeSampler(); RouteInfo routeDTO = SamplerUtils.getRandomRouteFromRepo(context.getIntParameter(ROUTES_TOUSE_KEY)); offer = FreightProvider.createRandomFreight(routeDTO, createUserWithLoginOnly(context)); freightOffer = connectTransformer.fromDTO(offer); String xmlOfferString = connectTransformer.toXML(freightOffer); // <- it fails here.
I take the date from CSV file and converting to DTO object. This method returns to me
FreightOfferDetail.
Here is snippet from this method:
public FreightOfferDetail freightFromDTO(FreightOfferDTO freightDTO, boolean fullFormat){ FreightOfferDetail freight = new FreightOfferDetail(); freight.setFreightId(freightDTO.getIds().getAtosId()); freight.setId(freightDTO.getIds().getFxId()); // ...
How to marshal object to XML file, at this case?
-
catch23 about 8 yearsI tried your suggestion. Result is the same -
javax.xml.bind.MarshalException - with linked exception: [com.sun.istack.SAXException2 ...
-
Alain Van Hout about 8 yearsCould have you include the entire stack trace? The exception type doesn't say a lot without the accompanying exception message. And the actual marshalling call would help to narrow it down (i.e. what type of object is actually being marshalled?).
-
catch23 about 8 yearsView the question. It contains exactly this exception.
-
Alain Van Hout about 8 yearsOkay, I'm just asking because in the original question you seemed to not have noticed that the exception did not refer to the class that you pointed out as indeed having that annotation.
-
Alain Van Hout about 8 yearsthat snippet doesn't include an actual toXml() call, and the Detail class contains List<Contact> field. Is that field annotated with the needed XML annotations? And based on the initial feedback, could you update the class definition annotations?
-
catch23 about 8 yearsContact has only
XmlAccessorType
. About which class definition have you exactly talked? -
Alain Van Hout about 8 yearsI'm talking about FreightOfferDetail (rather than FreightOffer) since that's what's mentioned in the original stacktrace message. To reiterate: the exception indicates that you are converting a Detail directly and that it therefore needs that one annotation.
-
catch23 almost 6 yearsOn that project we had to use ant as a build tool. And my main goal is marshal object to XML instead of wrapping fault message. I have exception stack trace from a console.