Skip to main content

@XmlElementRef behaviour change

5 replies [Last post]
calavera
Offline
Joined: 2007-07-05
Points: 0

I've got code similar to:

<br />
@XmlRootElement<br />
@XmlAccessorType(value = XmlAccessType.PROPERTY)<br />
public class Fiber, F extends DomainElement<?>> implements<br />
		Comparable>, Serializable {<br />
	@XmlElementRef(type = Object.class)<br />
	@XmlJavaTypeAdapter(DomainElementAdapter.class)<br />
	public E getFiberId() {<br />
		return fiberId;<br />
	}<br />
	...<br />
}</p>
<p>public interface DomainElement extends Comparable, Serializable {<br />
	...<br />
}</p>
<p>@XmlRootElement<br />
public enum StockingPolicy implements DomainElement {<br />
	STOCKED, NON_STOCKED, TOTAL;<br />
	...<br />
}</p>
<p>@XmlRootElement<br />
public class Period implements DomainElement{<br />
	...<br />
}<br />

I'm using DomainElementAdapter for transforming enums into jaxb friendly object (since they haven't got constructors). It works perfectly with jaxb 2.0.1 but on 2.0.5 serializing throws exception saying that Object.class is not known to XmlElementRef annotation. Anyone knows the cause of such a behaviour?

Message was edited by: calavera

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
kohsuke
Offline
Joined: 2003-06-09
Points: 0

You didn't give me the signature of DomainElementAdapter, but I wonder if it's just a matter of getting rid of "type=Object.class" ?

calavera
Offline
Joined: 2007-07-05
Points: 0

[code]
public class DomainElementAdapter extends XmlAdapter

{ @Override public Object marshal(Object arg0) throws Exception { if (arg0 instanceof Enum) { return adaptEnum(arg0.getClass().getName(), ((Enum) arg0).toString()); } return arg0; } private EnumSerializator adaptEnum(String className, String enumValue) { EnumSerializator es = new EnumSerializator(); es.setEnumName(className); es.setEnumValue(enumValue); return es; } @Override public Object unmarshal(Object arg0) throws Exception { if (arg0 instanceof DomainElement) { return arg0; } if (arg0 instanceof EnumSerializator) { EnumSerializator es = (EnumSerializator) arg0; if (StockingPolicy.class.getName().equals(es.getEnumName())) { return Enum.valueOf(StockingPolicy.class, es.getEnumValue()); } ... } } } @XmlRootElement public class EnumSerializator { private String enumName = null; private String enumValue = null; public String getEnumName() { return enumName; } public void setEnumName(String enumName) { this.enumName = enumName; } public String getEnumValue() { return enumValue; } public void setEnumValue(String enumValue) { this.enumValue = enumValue; } } [/code]
kohsuke
Offline
Joined: 2003-06-09
Points: 0

How about replacing @XmlElementRef by @XmlAnyElement?

calavera
Offline
Joined: 2007-07-05
Points: 0

In that case DomainElementAdapter receives com.sun.org.apache.xerces.internal.dom.ElementNSImpl object to unmarshall and it can't handle it in any way, returning it as it is causes exception since ElementNSImpl doesn't implement DomainElement interface.

With [code]@XmlObjectRef(type=object)[/code] on 2.0.5 and 2.1.3 exact error is descripted with following message:
[code]
XmlElementRef points to a non-existent class.
this problem is related to the following location:
at public se.sync.webobjects.charts.DomainElement se.sync.webobjects.charts.Fiber.getFiberId()
at se.sync.webobjects.charts.Fiber
[/code]

Message was edited by: calavera

kohsuke
Offline
Joined: 2003-06-09
Points: 0

Would it be possible to file this as an issue https://jaxb.dev.java.net/issues/ with a test case?

I think Id like to see the whole thing and run it by myself.