title: Java, Jackson, Custom deserializer with extended classes
body: <p>Using Jackson 2.10., I am trying to write a custom deserializer for a base class, but I have to deserialize fields with unknown field name. Then there are extended class that can also extend this serializer.</p>
  
  <p>I have tried to use the @AnyGetter, and @AnySetter to accomplish it, and it kind of does work. Now I am just wondering if there is a way to do it through a custom deserializer.</p>
  
  <p>I could do it with a base class, but it fails when some class extends it.</p>
  
  <p>Here is the sample of what I have done.
  The following is just the base class and its serializer and how I used in in the main.</p>
  
  <pre class="lang-java prettyprint-override"><code>//BaseClass
  @JsonDeserialize(using = BaseClassDeserializer.class)
  public static class BaseClass {
    private ObjectNode customFields = JsonNodeFactory.instance.objectNode();
    private int baseInt;
  
    public int getBaseInt() {
      return baseInt;
    }
  
    public void setBaseInt(int baseInt) {
      this.baseInt = baseInt;
    }
  
    public JsonNode getCustomFields() {
      return customFields;
    }
  
    public void setCustomFields(ObjectNode customFields) {
      this.customFields = customFields;
    }
  
    public void putCustomFields(String key, JsonNode node) {
      this.customFields.set(key, node);
    }
  }
  </code></pre>
  
  <pre class="lang-java prettyprint-override"><code>// BaseClassDeserializer
  public static class BaseClassDeserializer extends StdDeserializer&lt;BaseClass&gt; {
    public BaseClassDeserializer() {
      this(null);
    }
  
    public BaseClassDeserializer(Class&lt;?&gt; vc) {
      super(vc);
    }
  
    @Override
    public BaseClass deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
        throws IOException, JsonProcessingException {
      BaseClass result = new BaseClass();
      JsonNode node = jsonParser.getCodec().readTree(jsonParser);
      result.setBaseInt((Integer) ((IntNode) node.get("baseInt")).numberValue());
      node.fieldNames();
      Iterator&lt;String&gt; iterator = node.fieldNames();
      while (iterator.hasNext()) {
        String fieldName = iterator.next();
        if (!"baseInt".equals(fieldName)) {
          result.putCustomFields(fieldName, node.get(fieldName));
        }
      }
      return result;
    }
  }
  </code></pre>
  
  <pre class="lang-java prettyprint-override"><code>// main
  public static void main(String[] args) throws JsonProcessingException {
    String json = "{\n"
        + "\t\"baseInt\": 1,\n"
        + "\t\"customObject\" : {\n"
        + "\t\t\"key\": \"value\"\n"
        + "\t},\n"
        + "\t\"customString\" : \"STRING\",\n"
        + "\t\"extendedString\" : \"STRING\"\n"
        + "}";
  
    ObjectMapper mapper = new ObjectMapper();
    BaseClass myClass = mapper.readValue(json, BaseClass.class);
  
  }
  </code></pre>
  
  <p>By going looking through the debugger, the fields are successfully loaded.</p>
  
  <p>Now I am trying to extend <code>BaseClass</code></p>
  
  <pre><code>// ExtendedClass
  public static class ExtendedClass extends BaseClass {
    @JsonProperty("extendedString")
    private String extendedString;
  
    public String getExtendedString() {
      return extendedString;
    }
  
    public void setExtendedString(String extendedString) {
      this.extendedString = extendedString;
    }
  }
  </code></pre>
  
  <pre><code>public static void main(String[] args) throws JsonProcessingException {
    String json = "{\n"
        + "\t\"baseInt\": 1,\n"
        + "\t\"customObject\" : {\n"
        + "\t\t\"key\": \"value\"\n"
        + "\t},\n"
        + "\t\"customString\" : \"STRING\",\n"
        + "\t\"extendedString\" : \"STRING\"\n"
        + "}";
  
    ObjectMapper mapper = new ObjectMapper();
    ExtendedClass myClass = mapper.readValue(json, ExtendedClass.class);
  
  }
  </code></pre>
  
  <p>And this crashes with a 
  <code>BaseClass cannot be cast to ExtendedClass</code> exception.</p>
  
  <p>I am guessing I have to pass along the deserialization to the child class' deserializer, but I cannot figure out how.</p>