Jackson Error: Java 8 date/time type not supported by default

Learn to fix the error ‘Java 8 date/time type not supported by default’ while serializing and deserializing Java 8 Date time classes using Jackson.

exceptions-notes

Learn to fix the error Java 8 date/time type not supported by default while serializing and deserializing Java 8 Date time classes using Jackson.

1. Problem

The error occurs when we serialize a Java object or deserialize JSON to POJO, and the POJO contains new Java 8 date time classes such as LocalDate, LocalTime, LocalDateTime etc.

For example, the following Employee class has LocalDate type field.

public class Employee {

  private Long id;
  private String name;
  private LocalDate dateOfBirth;
}

When we serialize an instance of this class, we get the following exception:

Exception in thread "main" java.lang.IllegalArgumentException: Java 8 date/time type `java.time.LocalDate` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: com.howtodoinjava.core.objectToMap.Employee["dateOfBirth"])
	at com.fasterxml.jackson.databind.ObjectMapper ._convert(ObjectMapper.java:4393)
	at com.fasterxml.jackson.databind.ObjectMapper .convertValue(ObjectMapper.java:4324)
	at com.howtodoinjava.core.objectToMap .ObjectToMapUsingJackson.main(ObjectToMapUsingJackson.java:25)

2. Solution

We must add support to new Java 8 classes in two steps to fix this error.

First, add the latest version of com.fasterxml.jackson.datatype:jackson-datatype-jsr310 Maven dependency.

<dependency>
  <groupId>com.fasterxml.jackson.datatype</groupId>
  <artifactId>jackson-datatype-jsr310</artifactId>
  <version>2.13.4</version>
</dependency>

Second, register the module JavaTimeModule either with ObjectMapper or JsonMapper based on what you are using.

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());

//or 

JsonMapper jsonMapper = new JsonMapper();
jsonMapper.registerModule(new JavaTimeModule());

After registering the JavaTimeModule, the above error will go away.

3. With Hibernate 6

The above solution may not work if you are facing this issue due to Hibernate 6 that serializes the objects using FormatMapper instances, and the default is JacksonJsonFormatMapper. The JacksonJsonFormatMapper basically uses a Jackson ObjectMapper instance constructed without any additional options.

To fix the issue, we need to create a custom instance of FormatMapper and assign it through a new property hibernate.type.json_format_mapper.

 spring.jpa.properties.hibernate.type.json_format_mapper=com.howtodoinjava.CustomJacksonJsonFormatMapper

And then create the mapper implementation as follows:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.hibernate.type.FormatMapper;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.jackson.JacksonJsonFormatMapper;

public class JacksonJsonFormatMapperCustom implements FormatMapper {

    private final FormatMapper delegate;

    public JacksonJsonFormatMapperCustom() {
        ObjectMapper objectMapper = createObjectMapper();
        delegate = new JacksonJsonFormatMapper(objectMapper);
    }

    private static ObjectMapper createObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper()
            .registerModule(new JavaTimeModule())
            .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        return objectMapper;
    }

    @Override
    public <T> T fromString(CharSequence charSequence, JavaType<T> javaType, WrapperOptions wrapperOptions) {
        return delegate.fromString(charSequence, javaType, wrapperOptions);
    }

    @Override
    public <T> String toString(T t, JavaType<T> javaType, WrapperOptions wrapperOptions) {
        return delegate.toString(t, javaType, wrapperOptions);
    }
}

Happy Learning !!

Leave a Comment

  1. thankyou so much , it works fine this code:

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(new JavaTimeModule());

    Reply
  2. fixed it by implementing a CustomJsonProvider which uses my ObjectMapper with registered JavaTimeModule:

    @Provider
    @Priority(value = 1)
    @Consumes({"application/json", "application/*+json", "text/json"})
    @Produces({"application/json", "application/*+json", "text/json"})
    public class CustomJsonProvider extends JacksonJsonProvider {
    
      private static final ObjectMapper OBJECT_MAPPER;
    
      static {
        // create the one and only instance
        OBJECT_MAPPER = LuminObjectMapper.getInstance();
      }
    
      public CustomJsonProvider() {
        super(OBJECT_MAPPER);
      }
    }
    
    Reply
  3. Works for me, when using Postman to send GET and PUT requests! But does not work, when using REST-Client from my WebApp to send PUT request. This results in error:
    RESTEASY004655: Unable to invoke request: java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type java.time.LocalDateTime not supported by default

    But I have registered following modules as seen in my server.log:
     a.l.m.c.r.LuminObjectMapper: registered module ‘com.fasterxml.jackson.datatype.jdk8.Jdk8Module’
     a.l.m.c.r.LuminObjectMapper: registered module ‘com.fasterxml.jackson.datatype.jsr310.JavaTimeModule’
     a.l.m.c.r.LuminObjectMapper: registered module ‘com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule’

    Probably a problem with resteasy client an Jackson ?!

    Any hints welcome !

    Thanx and regards,
    Rainer

    Reply
  4. can we register JodaMoudle also, along with JavaTimeModule, as the project is already using the joda time, from now we need to use java time, please suggest

    Reply

Leave a Comment

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.