jaxbunmarshalling

JAXB unmarshalling doesn't work when field is declared as List but works when same field is declared as ArrayList


I recently started working on a code which contains some JAXB serializable/deserializable classes. One of the classes has a few lists in it and I wanted to add a new list to it. The lists were initially declared as ArrayList. Similarly, the get methods were also returning ArrayList. I changed all of them to List and added the new list as well as List. But after that, I was not able to unmarshal the xml for this object into a JAVA object. When I change the fields back to ArrayList without any other change, the unmarshalling works fine. I have also tried to attach the DefaultValidationEventHandler to the Unmarshaller but it doesn't spit out any error while unmarshalling. Below is how the class looks like with class and variable names change

@XmlRootElement(name = "commandSet")
public class CommandSet {

    private final ArrayList<Command> xCommands;

    private final ArrayList<Command> yCommands;

    @Override
    @XmlElementWrapper(name = "xCommands")
    @XmlElement(name = "xCommand", type = Command.class)
    public ArrayList<Command> getXCommands() {
        return this.xCommands;
    }

    @Override
    @XmlElementWrapper(name = "yCommands")
    @XmlElement(name = "yCommand", type = Command.class)
    public ArrayList<Command> getYCommands() {
        return this.yCommands;
    }
}

When xCommands and yCommands are declared as List and the getters also return List, the unmarhsalling doesn't work.

In all the examples that I have found for unmarshalling lists, people have used List<> instead of ArrayList<>. Any ideas why is it not working for me with List<>?


Solution

  • Things I Noticed About Your Code

    There are a couple of weird things I notice about your code that may or may not factor into your problem. At the very least I suspect the model you are experiencing the problem with is different from the model you posted in your question.

    Complete Working Example

    Java Model

    CommandSet

    In this version of the CommandSet class I have made one of the properties type ArrayList and the other of type List to demonstrate that they both work. I have also removed the weird things about your code mentioned above.

    import java.util.*;
    import javax.xml.bind.annotation.*;
    
    @XmlRootElement
     public class CommandSet {
    
        private final ArrayList<Command> xCommands;
        private final List<Command> yCommands;
    
        public CommandSet() {
            xCommands = new ArrayList<Command>();
            yCommands = new ArrayList<Command>();
        }
    
        @XmlElementWrapper(name = "xCommands")
        @XmlElement(name = "xCommand")
        public ArrayList<Command> getXCommands() {
            return this.xCommands;
        }
    
        @XmlElementWrapper(name = "yCommands")
        @XmlElement(name = "yCommand")
        public List<Command> getYCommands() {
            return this.yCommands;
        }
    
    }
    

    Command

    public class Command {
    }
    

    Demo Code

    Demo

    import java.io.File;
    import javax.xml.bind.*;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance(CommandSet.class);
    
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            File xml = new File("input.xml");
            CommandSet commandSet = (CommandSet) unmarshaller.unmarshal(xml);
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(commandSet, System.out);
        }
    
    }
    

    input.xml/Output

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <commandSet>
        <xCommands>
            <xCommand/>
            <xCommand/>
        </xCommands>
        <yCommands>
            <yCommand/>
            <yCommand/>
        </yCommands>
    </commandSet>