Issue Details (XML | Word | Printable)

Key: JAXB-955
Type: Bug Bug
Status: Open Open
Priority: Major Major
Assignee: Iaroslav Savytskyi
Reporter: n4h0y
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
jaxb

RootElement classes unmarshaled to JAXBElement when there is another Class that has AnyElement

Created: 10/Apr/13 01:18 AM   Updated: 10/Apr/13 01:19 AM
Component/s: None
Affects Version/s: 2.2.6
Fix Version/s: None

Time Tracking:
Not Specified

Environment:

Windows 7, Java 7.19


Tags:
Participants: Iaroslav Savytskyi and n4h0y


 Description  « Hide

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;



n4h0y added a comment - 10/Apr/13 01:19 AM

I have working small isolated eclipse project to replicate this issue. Email me if you want, the fix should be simple.