智享未来打一生肖:JAXB Annotations - Mapping interfaces and @XmlElementWrapper
up vote2down votefavoriteshare [fb]share [tw]
I am having trouble with JAXB annotations for a field that is a list whose generified type is an interface. When I have it declared such as:
@XmlAnyElement
private List animals;
Every thing works correctly. But when I add a wrapper element, such as:
@XmlElementWrapper
@XmlAnyElement
private List animals;
I find that the Java object marshals correctly, but when I unmarshal the document created by marshaling, my list is empty. I have posted below the code to demonstrate this problem.
Am I doing something wrong, or is this a bug? I have tried it with version 2.1.12 and 2.2-ea with the same result.
I am working through the example for mapping interfaces with annotations located here:https://jaxb.dev.java.net/guide/Mapping_interfaces.html
@XmlRootElement
class Zoo {
@XmlElementWrapper
@XmlAnyElement(lax = true)
private List animals;
public static void main(String[] args) throws Exception {
Zoo zoo = new Zoo();
zoo.animals = new ArrayList();
zoo.animals.add(new Dog());
zoo.animals.add(new Cat());
JAXBContext jc = JAXBContext.newInstance(Zoo.class, Dog.class, Cat.class);
Marshaller marshaller = jc.createMarshaller();
ByteArrayOutputStream os = new ByteArrayOutputStream();
marshaller.marshal(zoo, os);
System.out.println(os.toString());
Unmarshaller unmarshaller = jc.createUnmarshaller();
Zoo unmarshalledZoo = (Zoo) unmarshaller.unmarshal(new ByteArrayInputStream(os.toByteArray()));
if (unmarshalledZoo.animals == null) {
System.out.println("animals was null");
} else if (unmarshalledZoo.animals.size() == 2) {
System.out.println("it worked");
} else {
System.out.println("failed!");
}
}
public interface Animal {}
@XmlRootElement
public static class Dog implements Animal {}
@XmlRootElement
public static class Cat implements Animal {}
}
interface annotations jaxblink|improve this questionasked Jul 21 '09 at 13:26623311
86% accept rate
feedback
4 Answers
activeoldestvotesup vote2down voteShould use @XmlElementRefs({ @XmlElementRef(type=Dog.class), @XmlElementRef(type=Cat.class)}) private List animals;
or use @XmlAnyElement(lax = true) only, and add Dog.class, Cat.class to JaxbContext
link|improve this answeranswered Feb 28 at 14:49212
feedbackup vote0down vote
When I run your test program with jdk1.6.0_20 it appears to work and I get the following output:
it worked
link|improve this answeranswered Jul 29 '10 at 13:2618k31426
What version of JAXB? – joekutner Nov 4 '10 at 19:41
I'm used the version of JAXB 2.1 included with jdk1.6.0_20. You can also try your example with MOXy JAXB (I'm the tech lead). We fixed a bug related to your question, you will need to use today's (Nov 4) or later EclipeseLink 2.2.0 nightly download: eclipse.org/eclipselink/downloads/nightly.php – Blaise Doughan Nov 4 '10 at 20:00feedbackup vote0down vote
Have you tried putting your annotations in your accessories? I also had this problem with @XmlElementWrapper before but i got it solved by putting the annotating my getter instead of annotating the field declaration.
link|improve this answeranswered Dec 20 '10 at 2:48111
feedbackup vote0down vote
When I run your test program with jdk1.6.0_20 it does not work, however one I changed annotation forlist from @XmlAnyElement(lax = true) to @XmlElementRefs({ @XmlElementRef(type=Dog.class), @XmlElementRef(type=Cat.class)}) then it works it does not matter that dog.class and cat.class are added to JAXBContext or not
link|improve this answeranswered Sep 12 at 18:171
(###)