jaxb
  1. jaxb
  2. JAXB-955

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

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 2.2.6
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None
    • Environment:

      Windows 7, Java 7.19

      Description

      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;

        Activity

        Hide
        n4h0y added a comment -

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

        Show
        n4h0y added a comment - I have working small isolated eclipse project to replicate this issue. Email me if you want, the fix should be simple.

          People

          • Assignee:
            Iaroslav Savytskyi
            Reporter:
            n4h0y
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated: