title: Guava Optional serialization with Jackson
body: <p>I am using <a href="https://github.com/FasterXML/jackson-datatype-guava" rel="nofollow">jackson-datatype-guava</a> along with <code>Jackson</code> to handle serialization of <code>Guava</code> objects. It all works fine with other objects but facing issue with <code>Optional</code>.</p>
  
  <p>I have a serializer deserializer interface from a framework with following methods which I am forced to use.</p>
  
  <pre><code>String toJson(Object object);
  
  &lt;T&gt; T fromJson(String json, Class&lt;T&gt; valueType);
  </code></pre>
  
  <p>That means my <code>Jackson</code> implementation of this interface which uses <code>ObjectMapper</code> also can only use following method on mapper.</p>
  
  <pre><code>mapper.readValue(json, valueType);
  </code></pre>
  
  <p>Which is not working in case of 'Optional'. </p>
  
  <pre><code>ObjectMapper mapper = new ObjectMapper();
  mapper.registerModule(new GuavaModule());
  
  mapper.readValue(mapper.writeValueAsString(Optional.of("string")), Optional.class);
  </code></pre>
  
  <p>This gives error saying <code>Null JavaType passed</code>. If I use <code>TypeReferece&lt;Optional&lt;String&gt;&gt;</code> in mapper, it works fine but is there a way to make it work with above interface?</p>
  
  <pre><code>//works fine but can't use this method as interface only accepts `Class` param.
  mapper.readValue(mapper.writeValueAsString(Optional.of("string")), new TypeReference&lt;Optional&lt;String&gt;&gt;(){});
  </code></pre>
  
  <p><strong>Update</strong></p>
  
  <p>I tried using 2.4.* versions of these library as suggested in comments and it's working fine for <code>Optional&lt;String&gt;</code> but does not still work for <code>Optional&lt;MyClass&gt;</code> where <code>MyClass</code> is simple pojo. Seems while deserializing, it thinks, json of <code>MyClass</code> is a map and converts it into <code>Optional&lt;Map&gt;</code>.</p>
  
  <pre><code>public class MyClass {
    private String name;
  
    public String getName() {
      return name;
    }
  
    public void setName(String name) {
      this.name = name;
    }
  }
  </code></pre>
  
  <p>Main Program:</p>
  
  <pre><code>MyClass obj = new MyClass();
  obj.setName("PAC");
  
  Optional&lt;MyClass&gt; obj1 = mapper.readValue(mapper.writeValueAsString(Optional.of(obj)), Optional.class);
  
  System.out.println(obj1); //prints as Map
  System.out.println(obj1.get().getName()); //Fails doing casting to MyClass
  </code></pre>
  
  <p>Output:</p>
  
  <pre><code>Exception in thread "main" Optional.of({name=PAC})
  java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to MyClass
  at OptionalTest.main(OptionalTest.java:22)
  </code></pre>
  
  <p>I also tried enabling default typing in mapper by <code>mapper.enableDefaultTyping()</code> but without any luck.</p>
  
  <p>Error at <code>mapper.readValue...</code> line after enabling default typing for <code>DefaultTyping.NON_FINAL</code></p>
  
  <pre><code>Invalid type id 'MyClass' (for id type 'Id.class'): Class MyClass is not assignable to com.google.common.base.Optional
  </code></pre>
  
  <p>Any further suggestions on this?</p>