Java – JAXBElement over an ArrayList

java, jaxb, marshalling

How to marshall a List of JAXBElement ?

I've got one POJO I cannot annotate, for instance:

public class APojo {private String aString;public APojo() {     super(); }public String getAString() {    return aString;}public void setAString(String aString) {    this.aString = aString;}}

So I'm doing this

APojo aPojo = new APojo();aPojo.setaString("a string");       JAXBElement<APojo> aJAXBedPojo = new JAXBElement<APojo>(new QName("apojo"), APojo.class, aPojo);

Which is correctly being marshaled.

However

List<JAXBElement<APojo>> list = new ArrayList<JAXBElement<APojo>>();

Is not working: when I' doing this

JAXBContext context = JAXBContext.newInstance(APojo.class, ArrayList.class);Marshaller m = context.createMarshaller();m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);m.marshal(list, System.out);

The runtime raises:

[com.sun.istack.internal.SAXException2: unable to marshal type "java.util.ArrayList" as an element because it is missing an @XmlRootElement annotation]

Which is normal since ArrayList is not annotated.

I know I can create a wrapper around ArrayList and annotate it with a @XmlRootElement so I can marshall this wrapper.

I'm looking for a solution without such a wrapper. Is it possible to create a JAXBElement with T being an ArrayList ? Or something similar ?

Best Solution

I would strongly recommend you use an XmlAdapter. You can simply register the adapter with your marshaller and it will use your annotated adapter class in place of the class you can't annotate.

Also, I think a wrapper class would be cleaner than trying to do something without a wrapper.

That being said, if you really wanted to, you could try the following:

List<JAXBElement<APojo>> list = new ArrayList<JAXBElement<APojo>>();JAXBElement<List<JAXBElement<APojo>>> listElement = new JAXBElement<List<JAXBElement<APojo>>>(new QName("apojolist"), List.class, list);