Search code examples
javaspring-bootjacksonjackson-modules

Java 8 LocalDateTime throwing exception for JsonString


I am testing my spring-boot code for Controller. for that I have written test like below

@RunWith(SpringRunner.class)
@WebMvcTest(AnimalController.class)
class AnimalControllerTest {

    @Autowired
    MockMvc mvc;
    @MockBean
    AnimalService animalService;

 

    @Test
    void addAnimal() throws Exception {
        AnimalDto animalDto = new AnimalDto();
        mvc.perform(MockMvcRequestBuilders
                   .post("/animal/add")
                   .content(asJsonString(new AnimalDto(null, "dog", LocalDateTime.now(),null, null, null, null)))
                   .contentType(MediaType.APPLICATION_JSON)
                   .accept(MediaType.APPLICATION_JSON))
                   .andExpect(status().isOk())
                   .andDo(MockMvcResultHandlers.print())
                   .andExpect(MockMvcResultMatchers.jsonPath("$.id").exists());

    }
}
 private String asJsonString(Object animalDto) {
        try {
            return new ObjectMapper().writeValueAsString(animalDto);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

but I am getting below error

java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: com.self.zoo.dto.AnimalDto["located"])

    at com.self.zoo.controller.AnimalControllerTest.asJsonString(AnimalControllerTest.java:63)
    at com.self.zoo.controller.AnimalControllerTest.addAnimal(AnimalControllerTest.java:50)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)


Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: com.self.zoo.dto.AnimalDto["located"])
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)

but I see in my classpath I see both JSR-310 jar as well Java faster-json-Java8 jar as well. enter image description here add below are there maven dependency:

    <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
        </dependency>
<dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-modules-java8</artifactId>
            <version>2.13.3</version>
            <type>pom</type>
            <scope>runtime</scope>
        </dependency>

Solution

  • In your code you are using a newly instantiated ObjectMapper which doesn't have all the modules registered. Instead use the pre-configured ObjectMapper provided by Spring Boot. You can @Autowired this into your test to use it.

    
    @Autowired
    private ObjectMapper mapper;
    
    private String asJsonString(Object animalDto) {
      try {
        return mapper.writeValueAsString(animalDto); 
      } catch (JsonProcessingException e) {
        throw new RuntimeException(e); 
      }
    }
    

    In your dependencies you don't need to add the jackson-datatype-jsr310 and jackson-modules-java8. Those are already, by default, provided by Spring Boot and automatically configured. So remove those dependencies.