jaxb-ri
jaxb-ri copied to clipboard
RootElement classes unmarshaled to JAXBElement when there is another Class that has AnyElement
When JAXBContext is instantiated based on multiple classes and one of the class contains a property that is annotated with @XmlAnyElement. This causes other classes to be stored in the rootmap not as ClassBeanInfoImpl, thus causing unmarshal process returning JAXBElement as opposed to the actual class. (See examples below to replicate it). The issue is in JAXBContextImpl.java line 333, [rootMap.put(n.getElementName(),bi);] Because it does not check whether there is already an entry there or not, thus all elements found in the typeSet is put into rootMap and overriding previous registry entry of ClassBeanInfoImpl for that Name.
//JaxbIssueWithAnyElement.java package jaxbissue;
import java.io.StringReader; import java.io.StringWriter;
import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller;
import org.uddi.api_v2.BindingDetail; import org.uddi.api_v2.BusinessEntityExt;
public class JaxbIssueWithAnyElement {
public static void main(String[] args) throws Exception
{ JAXBContext context = JAXBContext.newInstance(BindingDetail.class); JAXBContext context2 = JAXBContext.newInstance(BindingDetail.class, BusinessEntityExt.class); StringWriter writer = new StringWriter(); BindingDetail detail = new BindingDetail(); detail.setGeneric("test"); Marshaller marshaller = context.createMarshaller(); marshaller.marshal(detail, writer); StringReader reader = new StringReader(writer.toString()); StringReader reader2 = new StringReader(writer.toString()); Unmarshaller unmarshaller = context.createUnmarshaller(); Object object = unmarshaller.unmarshal(reader); System.out.println(object.getClass()); Unmarshaller unmarshaller2 = context2.createUnmarshaller(); Object object2 = unmarshaller2.unmarshal(reader2); System.out.println(object2.getClass()); }
}
//BindingDetail.java package org.uddi.api_v2;
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "bindingDetail") @XmlRootElement(name = "bindingDetail") public class BindingDetail {
protected String generic;
public String getGeneric()
{ return generic; }
public void setGeneric(String value)
{ this.generic = value; }
}
//BusinessEntityExt.java package org.uddi.api_v2;
import java.util.ArrayList; import java.util.List;
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAnyElement; import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "businessEntityExt") public class BusinessEntityExt {
@XmlAnyElement(lax = true) protected List<Object> any;
public List<Object> getAny() { if (any == null)
{ any = new ArrayList<Object>(); }
return this.any; }
}
// ObjectFactory.java package org.uddi.api_v2;
import javax.xml.bind.JAXBElement; import javax.xml.bind.annotation.XmlElementDecl; import javax.xml.bind.annotation.XmlRegistry; import javax.xml.namespace.QName;
@XmlRegistry public class ObjectFactory {
private final static QName _BindingDetail_QNAME = new QName( "urn:uddi-org:api_v2", "bindingDetail"); private final static QName _BusinessEntityExt_QNAME = new QName( "urn:uddi-org:api_v2", "businessEntityExt");
/**
- Create a new ObjectFactory that can be used to create new instances of
- schema derived classes for package: org.uddi.api_v2
- */ public ObjectFactory() { }
public BindingDetail createBindingDetail()
{ return new BindingDetail(); }
public BusinessEntityExt createBusinessEntityExt()
{ return new BusinessEntityExt(); }
@XmlElementDecl(namespace = "urn:uddi-org:api_v2", name = "bindingDetail") public JAXBElement<BindingDetail> createBindingDetail(BindingDetail value)
{ return new JAXBElement<BindingDetail>(_BindingDetail_QNAME, BindingDetail.class, null, value); }
@XmlElementDecl(namespace = "urn:uddi-org:api_v2", name = "businessEntityExt") public JAXBElement<BusinessEntityExt> createBusinessEntityExt( BusinessEntityExt value)
{ return new JAXBElement<BusinessEntityExt>(_BusinessEntityExt_QNAME, BusinessEntityExt.class, null, value); }
}
// package-info.java @javax.xml.bind.annotation.XmlSchema(namespace = "urn:uddi-org:api_v2", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) package org.uddi.api_v2;
Environment
Windows 7, Java 7.19
Affected Versions
[2.2.6]
- Issue Imported From: https://github.com/javaee/jaxb-v2/issues/955
- Original Issue Raised By:@glassfishrobot
- Original Issue Assigned To: @glassfishrobot
@glassfishrobot Commented Reported by n4h0y
@glassfishrobot Commented n4h0y said: I have working small isolated eclipse project to replicate this issue. Email me if you want, the fix should be simple.
@glassfishrobot Commented Was assigned to yaroska
@glassfishrobot Commented This issue was imported from java.net JIRA JAXB-955