title: How to use Jackson's ContextualDeserializer for root values?
body: <p>I'm trying to implement a generic deserializer for all classes that extend from a certain abstract class or implement a certain interface. In this example I'm using interface <code>StringConvertible</code>. I need to determine the concrete type and so that I can create an instance.</p>
  
  <p>An <a href="http://jackson-users.ning.com/forum/topics/deserialize-with-generic-type" rel="noreferrer">old forum post by Programmer Bruce</a> led me to using ContextDeserializer and it's working when the StringConvertible is a property in another class. </p>
  
  <p>But when I want to deserialize the StringConvertible directly, I can't find a way to get the concrete type because the <code>beanProperty</code> parameter is <code>null</code>. Apparently that is expected, according to <a href="http://jackson-users.ning.com/forum/topics/contextualserializer-and-beanproperty" rel="noreferrer">this question/answer</a> at the Jackson JSON User Group: 
  <code>
  The only case where property should be null is when serializing a "root value", meaning the object instance passed directly to ObjectMapper's (or ObjectWriter's) writeValue() method -- in this case there simply isn't a referring property. But otherwise it should always be passed.</code></p>
  
  <p>See main method below for an example of both cases:</p>
  
  <pre><code>@JsonDeserialize(using = StringConvertibleDeserializer.class)
  public final class SomeStringConvertible implements StringConvertible {
  
      private final String value;
  
      public SomeStringConvertible(final String value) {
  
          this.value = value;
      }
  
      @Override
      @JsonValue
      public String stringValue() {
  
          return value;
      }
  }
  
  public final class SomeWrapper {
  
      public SomeStringConvertible stringConvertible;
  
      public SomeWrapper() {
  
      }
  }
  
  
  public class StringConvertibleDeserializer extends StdDeserializer&lt;StringConvertible&gt; implements ContextualDeserializer {
  
      private final Class&lt;? extends StringConvertible&gt;    targetClass;
  
      StringConvertibleDeserializer() {
  
          super(StringConvertible.class);
  
          this.targetClass = null;
      }
  
      StringConvertibleDeserializer(final Class&lt;? extends StringConvertible&gt; targetClass) {
  
          super(StringConvertible.class);
  
          this.targetClass = targetClass;
      }
  
      @Override
      public JsonDeserializer&lt;?&gt; createContextual(final DeserializationContext deserializationContext, @Nullable final BeanProperty beanProperty)
                                                                                                                                                  throws JsonMappingException {
  
          final StringConvertibleDeserializer contextualDeserializer;
  
          // ====  Determine target type  =====
          final Class&lt;? extends StringConvertible&gt; targetClass;
          JavaType type = beanProperty.getType(); // -&gt; beanProperty is null when the StringConvertible type is a root value
          targetClass = (Class&lt;? extends StringConvertible&gt;) type.getRawClass();
  
          // ====  Create contextual deserializer  =====
          contextualDeserializer = new StringConvertibleDeserializer(targetClass);
  
          // ====  Return  =====
          return contextualDeserializer;
      }
  
      @Override
      public StringConvertible deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException, JsonProcessingException {
  
          final StringConvertible value;
  
          // ====  Create instance using the target type  =====
          if (targetClass.equals(SomeStringConvertible.class))
              value = new SomeStringConvertible(jsonParser.getText());
          else {
              throw new RuntimeException();
          }
  
          // ====  Return  =====
          return value;
      }
  
  }
  
  public final class JacksonModule extends SimpleModule {
  
      public JacksonModule() {
  
          super();
  
          addDeserializer(StringConvertible.class, new StringConvertibleDeserializer());
      }
  }
  
  public final class Main {
  
      public static void main(String[] args) {
  
          final ObjectMapper mapper = new ObjectMapper();
          mapper.registerModule(new JacksonModule());
  
          final String wrappedValueJSON = "{\"stringConvertible\":\"hello world\"}";
          final String rootValueJSON = "\"hello world\"";
  
          try {
              mapper.readValue(wrappedValueJSON, SomeWrapper.class);  // This works fine
              mapper.readValue(rootValueJSON, SomeStringConvertible.class);   // This causes a NPE in createContextual(...) because beanProperty is null
  
          } catch (JsonProcessingException e) {
              throw new RuntimeException(e);
          } catch (IOException e) {
              throw new RuntimeException(e);
          }
      }
  }
  </code></pre>
  
  <p><strong>Question:</strong> How can I get type concrete type in case of a root value? Or, if there is a better solution than this, what would you suggest instead?</p>