title: How to deserialize Joda DateTime using Jackson with Jersey 2 Client in Spring MVC?
body: <p>I've been bashing my head with this proof of concept for a while. I want to consume a REST endpoint that returns JSON payload with an ISO8601 UTC timestamp:</p>
  
  <pre><code>{  ...
    "timestamp" : "2014-08-20T11:51:31.233Z" 
  }
  </code></pre>
  
  <p>and I want to consume it using a command line Java client written as a Jersey 2 client with Jackson/Spring Boot. The marshalling POJO is defined as follows:</p>
  
  <pre><code>@JsonIgnoreProperties(ignoreUnknown = true)
  @JsonInclude(Include.NON_NULL)
  public class GreetingResource
  {
    @JsonProperty("timestamp")
    private DateTime date;
  
    ...
  }
  </code></pre>
  
  <p>After following recommendations shown in: </p>
  
  <p><a href="https://jersey.java.net/documentation/latest/user-guide.html#json.jackson" rel="noreferrer">https://jersey.java.net/documentation/latest/user-guide.html#json.jackson</a></p>
  
  <p>and using the following Gradle dependencies:</p>
  
  <pre><code>dependencies {
      compile("org.springframework.boot:spring-boot-starter")
      compile("org.springframework.boot:spring-boot-starter-logging")
      compile("joda-time:joda-time")
      compile("com.fasterxml.jackson.core:jackson-core")
      compile("com.fasterxml.jackson.core:jackson-annotations")
      compile("com.fasterxml.jackson.core:jackson-databind")
      compile("com.fasterxml.jackson.datatype:jackson-datatype-joda")
      compile("com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.3.3")
      compile("org.apache.commons:commons-lang3:3.3.2")
      compile("org.glassfish.jersey.core:jersey-client:2.2")
      compile("org.glassfish.jersey.media:jersey-media-json-jackson:2.2")
      testCompile("org.springframework.boot:spring-boot-starter-test")
  }
  </code></pre>
  
  <p>I always get this error:</p>
  
  <pre><code>Exception in thread "main" javax.ws.rs.ProcessingException: Error reading entity from input stream.
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:849)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:768)
    at org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:96)
    at org.glassfish.jersey.client.ScopedJaxrsResponse.access$001(ScopedJaxrsResponse.java:56)
    at org.glassfish.jersey.client.ScopedJaxrsResponse$1.call(ScopedJaxrsResponse.java:77)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:397)
    at org.glassfish.jersey.client.ScopedJaxrsResponse.readEntity(ScopedJaxrsResponse.java:74)
    at client.GreetingClient.processResponse(GreetingClient.java:62)
    at client.GreetingClient.performGet(GreetingClient.java:53)
    at client.GreetingService.internalLoadGreeting(GreetingService.java:44)
    at client.GreetingService.LoadGreeting(GreetingService.java:27)
    at client.Application.main(Application.java:25)
  Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class org.joda.time.DateTime] from String value ('2014-08-20T12:19:36.358Z'); no single-String constructor/factory method (through reference chain: client.GreetingResource["timestamp"])
    at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator._createFromStringFallbacks(StdValueInstantiator.java:428)
    at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:299)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1150)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:139)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:126)
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:525)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:99)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:242)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:118)
    at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1233)
    at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:677)
    at com.fasterxml.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:777)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:188)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:134)
  </code></pre>
  
  <p>I have given up. What am I doing wrong? </p>
  
  <p>The client is configured as follows: </p>
  
  <pre><code>import javax.ws.rs.client.Client;
  import javax.ws.rs.client.ClientBuilder;
  import javax.ws.rs.client.Invocation.Builder;
  import javax.ws.rs.client.WebTarget;
  import org.glassfish.jersey.client.ClientConfig;
  
  ...
  
  @Component
  public class GreetingClient
  {
  
    private final WebTarget serviceWebTarget;
  
    {
      ClientConfig config = new ClientConfig();
      config.register(MyObjectMapperProvider.class);
      config.register(JacksonFeatures.class);
      Client client = ClientBuilder.newClient(config);
      this.serviceWebTarget = client.target("http://myserver:8080");
    }
  
    ...  
  
  }
  </code></pre>
  
  <p>The registered provider is defined as (in the same package as the client):</p>
  
  <pre><code>@Provider
  public class MyObjectMapperProvider implements ContextResolver&lt;ObjectMapper&gt;
  {
    private final static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
  
  
    @Override
    public ObjectMapper getContext(Class&lt;?&gt; type)
    {
      final ObjectMapper result = new JodaMapper();
      result.setDateFormat(dateFormat);
      return result;
    }
  
  }
  </code></pre>
  
  <p>I have tried with/without registering the provider and also annotating the field to use DateTimeDeserializer (through @JsonDeserialize) - only to get an error because "there is no default no-arg constructor available". </p>
  
  <p>If I use standard java.util.Date instead with </p>
  
  <pre><code>@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
  </code></pre>
  
  <p>it works like a breeze.</p>
  
  <p>Any clues? Thanks for your help.</p>