javaee / jaxb-v2

Other
210 stars 100 forks source link

Unmarshaling of bound generic Type fails #1103

Open glassfishrobot opened 8 years ago

glassfishrobot commented 8 years ago

On a generic typed Bean-Class, an Element of that Generic type may be marshaled and unmarshaled - this works. But if the Generic Type gets bound to an abstract class, the unmarshaling Fails.

In the following example, I need a boundary for any type of Number, but JAXB tries to unmarshal this by instantiating to Number, which is abstract. Ommitting the boundary or changing it to an instantiable type (like Object) solves the issue, but weakens the generics.

**JaxbTester.java**package de.panbytes.playground.jaxb;

import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

public class JaxbTester {

  /*
   * AbstractContainer<T> -> works, but misses boundaries
   * AbstractContainer<T extends Object> -> works, but boundaries are too large
   * AbstractContainer<T extends Number> -> fails: "Exception in thread "main" javax.xml.bind.UnmarshalException: Unable to create an instance of java.lang.Number"
   */
  static abstract class AbstractContainer<T /* extends Number */> {

    @XmlElement
    T someNumber;

  }

  @XmlRootElement
  static class ContainerImpl<T extends Number> extends AbstractContainer<T> {

    @SuppressWarnings("unused")
    private ContainerImpl() {
      // for JAXB
    }

    public ContainerImpl(final T someNumber) {
      this.someNumber = someNumber;
    }

  }

  /**
   * @param args
   */
  public static void main(final String[] args) throws Exception {
    final AbstractContainer<Double> containerA = new ContainerImpl<>(42.5);

    final JAXBContext context = JAXBContext.newInstance(ContainerImpl.class);

    final Marshaller marshaller = context.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

    final StringWriter stringWriter = new StringWriter();
    marshaller.marshal(containerA, stringWriter);
    final String xmlString = stringWriter.toString();

    System.out.println(xmlString);

    final Unmarshaller unmarshaller = context.createUnmarshaller();
    unmarshaller.setEventHandler(event -> {
      System.err.println("!! " + event.getMessage() + " - " + event.getLocator() + "\n");
      return true;
    });

    final Object unmarshal = unmarshaller.unmarshal(new StringReader(xmlString));
    System.out.println("unmarshal: " + unmarshal.toString());
  }

}

The marshaled XML is the following, in each case containing the correct xsi:type="xs:double".

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<containerImpl>
    <someNumber xsi:type="xs:double" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">42.5</someNumber> </containerImpl>

Environment

Windows 10 / jdk1.8.0_91 / eclipse neon 4.6.0

Affected Versions

[2.2.8 (JDK 8)]

glassfishrobot commented 8 years ago

Reported by poseidonFS

glassfishrobot commented 8 years ago

Was assigned to yaroska

glassfishrobot commented 7 years ago

This issue was imported from java.net JIRA JAXB-1103