2

I am trying to wrap 2 Classes, that are built following the Composite pattern, with JAXB.

The whole thing i built like this:

public interface ICriterion {String somemethod(String arg);}

@XmlRootElement(name = "criterion")
@XmlAccessorType(XmlAccessType.FIELD)
public class Criterion implements ICriterion {
    @XmlElement String name;
    @XmlElement String data;
    //getter, setter, somemethod(), Criterion(), Criterion(String, String)
}

@XmlRootElement(name = "criteria")
@XmlAccessorType(XmlAccessType.FIELD)
public class Criteria implements ICriterion {
    @XmlAnyElement(lax=true)
    private final List<ICriterion> criteria;
    //getter, setter, somemethod(), 
    Criteria(){criteria = new ArrayList<>();}
    Criteria(List<ICriterion>)...
}

i took this solution from this answer

It works fine for marshalling - i can provide a Criteria, which contain a list of Criteria and Criterions, it gets marshaled to xml correctly.

What does not work however is unmarshaling a string to an Object

String request = 
<criteria>
    <criteria>
        <criterion>
            <name>number1</value>
            <data>123123</token>
        </criterion>
        <criterion>
            <name>number2</value>
            <data>1223323</token>
        </criterion>
    </criteria>
    <criterion>
        <name>number3</value>
        <data>1212</token>
    </criterion>
</criteria>


JAXBContext ctx = JAXBContext.newInstance(Criteria.class, Criterion.class);
    StringReader reader = new StringReader(request);
    Criteria wrapped = (Criteria) ctx.createUnmarshaller().unmarshal(reader);

gives:

java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(AbstractList.java:148)
    at java.util.AbstractList.add(AbstractList.java:108)

I've tried other ways that are avaiable through online sources like:

@XmlElementRefs({ @XmlElementRef(type=Criterion.class), @XmlElementRef(type=Criteria.class)})

@XmlElements({@XmlElement(type=Criteria.class),@XmlElement(type=Criterion.class)})

which do not give an error, but result in the List being empty instead. The solution to this problem, is using @XmlAnyElement(lax=true), which does not work for me.

My first guess was, that somehow the List is not initialized correctly in my Constructor and JAXB uses some kind of fixed size list. My countermeasure was to explicitly initialize the list in the no-Args constructor

Criteria(){criteria = new ArrayList<>();}

The problem also is not solved by explicitly making "critera" an ArrayList<> instead of List<>.

What am I missing?

Community
  • 1
  • 1
billdoor
  • 1,999
  • 4
  • 28
  • 54

0 Answers0