Search code examples
javaxmljaxbmoxy

MOXy JAXB breaks on XmlIDREF to type that has an enum attribute


I have set up a minimal working example of the problem I have. These are the JAXB classes.

moxytest/A.java

package moxytest;
@XmlRootElement
public class A {

    @XmlElement(name = "b")
    public List<B> bs;

    @XmlElement(name = "c")
    public List<C> cs;
}

moxytest/B.java

package moxytest;    
public class B {

    @XmlAttribute
    @XmlID
    public String id;

    @XmlAttribute
    public EnumD md;
}

moxytest/C.java

package moxytest;
public class C {

    @XmlAttribute
    @XmlIDREF
    public B b;
}

moxytest/EnumD.java

package moxytest;
@XmlEnum
public enum EnumD {

    VALUE1, VALUE2, VALUE3
}

Example input:

<?xml version="1.0" encoding="UTF-8" ?>
<a>
    <b id="b1" md="VALUE1"/>
    <b id="b2" md="VALUE2"/>
    <b id="b3" md="VALUE3"/>
    <c b="b2"/>
    <c b="b1"/>
    <c b="b3"/>
</a>

So C elements are referencing B elements by id, and B elements have an Enum attribute.

This line of Java code

JAXBContext context = JAXBContext.newInstance(A.class);

Produces an exception with the following message:

The @XmlAttribute property b in type moxytest.C must reference a type that maps to text in XML. moxytest.B cannot be mapped to a text value.

I have been debugging and reading some lines of MOXy source code. That is how I was able to set up this minimal example. The JDK implementation works fine.

EDIT:

I am using EclipseLink 2.6.0 (thanks Santhosh Kumar Tekuri)


Solution

  • I tested your code with following maven dependency:

    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>2.5.0</version>
    </dependency>
    

    i placed jaxb.properties in same package where model classes exist. this file contains:

    javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
    

    and it works fine. below is my unmarshalling code:

    public static void main(String[] args) throws Exception{
        JAXBContext context = JAXBContext.newInstance(A.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        Object obj = unmarshaller.unmarshal(new File("input.xml"));
        System.out.println(obj);
    }
    

    make sure you are using same moxy version I am using.