Reputation: 33
Is it possible to use @XmlValue annotation on a referenced object annotated with @XmlElementRef? The goal is to produce the following XML output:
<foo>
<bar>Blah</bar>
</foo>
Given the following example JAXBContext initialization is throwing a NPE: at com.sun.xml.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:128)
Foo Class
@XmlRootElement(name = "foo")
public class Foo
{
@XmlElementRef
private Bar bar;
}
Bar Class
@XmlRootElement(name = "bar")
public class Bar extends BarBase // BarBase is annotated with @XmlTransient
{
@XmlValue
private String value;
}
Is there any way to achieve the desired output based on the implementation? I've been looking into Adapters, but haven't been successful at implement one. Thanks in advance!
Upvotes: 3
Views: 1340
Reputation: 21978
I'm here for exactly the same issue. This issue is still alive with 1.8.0_77
.
I bypassed with an additional dummy attribute as user3345125
mentioned.
@XmlAttribute
public String getNothing() {
return null;
}
For anyone would like to trace. https://github.com/javaee/jaxb-v2/issues/1027
Upvotes: 0
Reputation: 11
@blaise - as a workaround create an optional @XmlAttribute
or @XmlElement
within the Bar
class
Upvotes: 1
Reputation: 148977
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
JAXB RI Issue Confirmed
I have been able to confirm the issue you are seeing with the JAXB RI. I get the following stack trace:
Exception in thread "main" java.lang.NullPointerException
at com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:113)
at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:166)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:494)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:311)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:126)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1148)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:130)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:248)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:235)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:445)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:637)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
at forum14490548.Demo.main(Demo.java:10)
This is a bug in the JAXB RI and I would recommend opening a ticket at the following link:
Option #1 - Use an Alternate Mapping with JAXB RI
The following mapping appears to work with the JAXB RI (using @XmlElement
instead of @XmlElementRef
.
import javax.xml.bind.annotation.*;
@XmlRootElement(name = "foo")
public class Foo
{
@XmlElement
private Bar bar;
}
Option #2 - Use an Alternate JAXB (JSR-222) Provider
Your mappings are correct. If you use another JAXB (JSR-222) provider such as EclipseLink MOXy you will not get this exception. Below is a link that explains how to use MOXy as your JAXB provider:
Upvotes: 3