title: Jackson (de)serialization of Java8 date/time by a JAX-RS client
body: <p>I'm making a serivce client for a REST endpoint, using a JAX-RS client for the HTTP requests and Jackson to (de)serialize JSON entities. In order to handle JSR-310 (Java8) date/time objects I added the <code>com.fasterxml.jackson.datatype:jackson-datatype-jsr310</code> module as a dependency to the service client, but I didn't get it to work.</p>
  
  <p><strong>How to configure JAX-RS and/or Jackson to use the jsr310 module?</strong></p>
  
  <p>I use the following dependencies:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;dependency&gt;
    &lt;groupId&gt;javax.ws.rs&lt;/groupId&gt;
    &lt;artifactId&gt;javax.ws.rs-api&lt;/artifactId&gt;
    &lt;version&gt;${jax-rs.version}&lt;/version&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;com.fasterxml.jackson.core&lt;/groupId&gt;
    &lt;artifactId&gt;jackson-annotations&lt;/artifactId&gt;
    &lt;version&gt;${jackson.version}&lt;/version&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;com.fasterxml.jackson.datatype&lt;/groupId&gt;
    &lt;artifactId&gt;jackson-datatype-jsr310&lt;/artifactId&gt;
    &lt;version&gt;${jackson.version}&lt;/version&gt;
  &lt;/dependency&gt;
  </code></pre>
  
  <p>I don't want to make the service client (which is released as a library) dependent on any specific implementation – like Jersey, so I only depend on the JAX-RS API. To run my integration tests I added:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;dependency&gt;
    &lt;groupId&gt;org.glassfish.jersey.core&lt;/groupId&gt;
    &lt;artifactId&gt;jersey-client&lt;/artifactId&gt;
    &lt;version&gt;${jersey.version}&lt;/version&gt;
    &lt;scope&gt;test&lt;/scope&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.glassfish.jersey.inject&lt;/groupId&gt;
    &lt;artifactId&gt;jersey-hk2&lt;/artifactId&gt;
    &lt;version&gt;${jersey.version}&lt;/version&gt;
    &lt;scope&gt;test&lt;/scope&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.glassfish.jersey.media&lt;/groupId&gt;
    &lt;artifactId&gt;jersey-media-json-jackson&lt;/artifactId&gt;
    &lt;version&gt;${jersey.version}&lt;/version&gt;
    &lt;scope&gt;test&lt;/scope&gt;
  &lt;/dependency&gt;
  </code></pre>
  
  <p>Instantiation of the JAX-RS client is done in a factory object, as follows:</p>
  
  <pre class="lang-java prettyprint-override"><code>import javax.ws.rs.Produces;
  import javax.ws.rs.client.Client;
  import javax.ws.rs.client.ClientBuilder;
  
  @Produces
  public Client produceClient() {
      return ClientBuilder.newClient();
  }
  </code></pre>
  
  <p>A typical DTO looks like this:</p>
  
  <pre class="lang-java prettyprint-override"><code>import com.fasterxml.jackson.annotation.JsonCreator;
  import com.fasterxml.jackson.annotation.JsonProperty;
  import com.fasterxml.jackson.annotation.JsonPropertyOrder;
  
  import java.time.Instant;
  
  import static java.util.Objects.requireNonNull;
  
  @JsonPropertyOrder({"n", "t"})
  public final class Message {
  
      private final String name;
      private final Instant timestamp;
  
      @JsonCreator
      public Message(@JsonProperty("n") final String name,
                     @JsonProperty("t") final Instant timestamp) {
          this.name = requireNonNull(name);
          this.timestamp = requireNonNull(timestamp);
      }
  
      @JsonProperty("n")
      public String getName() {
          return this.name;
      }
  
      @JsonProperty("t")
      public Instant getTimestamp() {
          return this.timestamp;
      }
  
      // equals(Object), hashCode() and toString()
  }
  </code></pre>
  
  <p>Requests are done like this:</p>
  
  <pre class="lang-java prettyprint-override"><code>import javax.ws.rs.client.Entity;
  import javax.ws.rs.client.WebTarget;
  import javax.ws.rs.core.MediaType;
  
  public final class Gateway {
  
      private final WebTarget endpoint;
  
      public Message postSomething(final Something something) {
          return this.endpoint
                  .request(MediaType.APPLICATION_JSON_TYPE)
                  .post(Entity.json(something), Message.class);
      }
  
      // where Message is the class defined above and Something is a similar DTO
  }
  </code></pre>
  
  <p>JSON serialization and deserialization works fine for Strings, ints, BigIntegers, Lists, etc. However, when I do something like <code>System.out.println(gateway.postSomthing(new Something("x", "y"));</code> in my tests I get the following exception:</p>
  
  <pre class="lang-none prettyprint-override"><code>com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.Instant` (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('Fri, 22 Sep 2017 10:26:52 GMT')
   at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 1, column: 562] (through reference chain: Message["t"])
          at org.example.com.ServiceClientTest.test(ServiceClientTest.java:52)
  Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
  Cannot construct instance of `java.time.Instant` (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('Fri, 22 Sep 2017 10:26:52 GMT')
   at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 1, column: 562] (through reference chain: Message["t"])
          at org.example.com.ServiceClientTest.test(ServiceClientTest.java:52)
  </code></pre>
  
  <p>From which I conclude that Jackson doesn't know how to deserialize Strings into Instants. I found blogs and SO questions about this topic, but I found no clear explanation on how to make it work.</p>
  
  <p>Note that I'd like the service client to handle date strings like <code>"Fri, 22 Sep 2017 10:26:52 GMT"</code> as well as <code>"2017-09-22T10:26:52.123Z"</code>, but I want it to always serialize to ISO 8601 date strings.</p>
  
  <p>Who can explain how to make deserialization into an <code>Instant</code> work?</p>