title: JAXB and inheritance
body: <p>I am trying to read a JSON file like:</p>
  
  <pre><code>{
    "a": "abc",
    "data" : {
        "type" : 1,
        ...
    }
  }
  </code></pre>
  
  <p>where the ... part is replaceable based on the type like:</p>
  
  <pre><code>{
    "a": "abc",
    "data" : {
        "type" : 1,
        "b" : "bcd"
    }
  }
  </code></pre>
  
  <p>or: </p>
  
  <pre><code>{
    "a": "abc",
    "data" : {
        "type" : 2,
        "c" : "cde",
        "d" : "def",
    }
  }
  </code></pre>
  
  <p>For the life of me I cannot figure out the proper JAXB annotations/classes to use to make this happen.
  I don't have an issue moving the type variable outside of the data block if needed.</p>
  
  <p>I'm using Glassfish 3.1.2.2.</p>
  
  <p>Edit: </p>
  
  <p>Based on the code provided by Perception I did a quick attempt... doesn't work in glassfish though:</p>
  
  <pre><code>@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = As.PROPERTY, property = "type")
  @JsonSubTypes(
  {
      @JsonSubTypes.Type(value = DataSubA.class, name = "1"),
      @JsonSubTypes.Type(value = DataSubB.class, name = "2") 
  })
  @XmlRootElement
  public abstract class Data implements Serializable 
  {
      private static final long serialVersionUID = 1L;
  
      public Data() 
      {
          super();
      }
  }
  
  @XmlRootElement
  @XmlAccessorType(XmlAccessType.NONE)
  public class DataSubA 
      extends Data 
  {
      private static final long serialVersionUID = 1L;
  
      @XmlElement
      private BigDecimal expenditure;
  
      public DataSubA() {
          super();
      }
  
      public DataSubA(final BigDecimal expenditure) {
          super();
          this.expenditure = expenditure;
      }
  
      @Override
      public String toString() {
          return String.format("%s[expenditure = %s]\n", 
                               getClass().getSimpleName(), getExpenditure());
      }
  
      public BigDecimal getExpenditure() {
          return expenditure;
      }
  
      public void setExpenditure(BigDecimal expenditure) {
          this.expenditure = expenditure;
      }
  }
  
  @XmlRootElement
  @XmlAccessorType(XmlAccessType.NONE)
  public class DataSubB 
      extends Data 
  {
      private static final long serialVersionUID = 1L;
  
      @XmlElement
      private String name;
  
      @XmlElement
      private Integer age;
  
      public DataSubB() 
      {
          super();
      }
  
      public DataSubB(final String name, final Integer age) 
      {
          super();
          this.name = name;
          this.age = age;
      }
  
      @Override
      public String toString() 
      {
          return String.format("%s[name = %s, age = %s]\n", 
                               getClass().getSimpleName(), getName(), getAge());
      }
  
      public String getName() {
          return name;
      }
  
      public void setName(String name) {
          this.name = name;
      }
  
      public Integer getAge() {
          return age;
      }
  
      public void setAge(Integer age) {
          this.age = age;
      }
  }
  
  @XmlRootElement
  @XmlAccessorType(XmlAccessType.NONE)
  public class DataWrapper
  { 
      @XmlElement
      private Data data;
  
      public Data getData() {
          return data;
      }
  
      public void setData(Data data) {
          this.data = data;
      }
  }
  </code></pre>
  
  <p>And a simple POST that takes it in:</p>
  
  <pre><code>@Stateless
  @Path("x")
  public class Endpoint
  {
      @POST
      @Consumes(
      {
          MediaType.APPLICATION_JSON,
      })
      @Produces(
      {
          MediaType.APPLICATION_JSON,
      })
      public String foo(final DataWrapper wrapper)
      {
          return ("yay");
      }
  }
  </code></pre>
  
  <p>When I pass in JSON like:</p>
  
  <pre><code>{
      "data" : 
      {
          "type" : 1,
          "expenditure" : 1
      }
  }
  </code></pre>
  
  <p>I get a message like:</p>
  
  <pre><code>Can not construct instance of Data, problem: abstract types can only be instantiated with additional type information
   at [Source: org.apache.catalina.connector.CoyoteInputStream@28b92ec1; line: 2, column: 5] (through reference chain: DataWrapper["data"])
  </code></pre>