'Getting conversion issue after migrating jackson-databind from 2.11.4 to 2.12.13.2

We have recently migrated jackson-databind from 3.11.4 to 3.12.13.2 version and springframework from 5.2.19.RELEASE to 5.2.22.RELEASE. after the migration we see below exception

java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type java.time.Instant not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (

To fix the issue i have added below code

mapper = new ObjectMapper();

    mapper.registerModule(new Jdk8Module());
    mapper.registerModule(new JavaTimeModule());

which fixed the issue, but i see conversation error now INSTANT type conversation.

expected is "myTime":{"epochSecond":1627413300,"nano":0}

but it is coming as "myTime":1.6274133E9

error : Reason is: Expected a OBJECT, instead got NUMBER for key myTime


working code with older version

pom dependencies -

jackson-databind - 2.11.4 jackson-datatype-jsr310 - 2.11.4

sample code

public class ObjectMapperTest {
 public static void main(String[] args) {

     try{
            ObjectMapper o = new ObjectMapper();
        
           
           Message message = new Message();
           System.out.println(message);
           String s2= o.writeValueAsString(message);
           System.out.println(s2);
         JsonNode i3=   o.readTree(s2);
           System.out.println(i3);
           
     } catch (Exception e) {
         e.printStackTrace();
    }
}

 static class Message
 { 
     private String source;
     @JsonFormat(shape = JsonFormat.Shape.NUMBER, timezone = "UTC")
     private Instant timestamp = Instant.now();
     
    @Override
    public String toString() {
        return "Message [source=" + source + ", timestamp=" + timestamp + "]";
    }
 }

}

output

  Message [source=null, timestamp=2022-05-06T12:28:49.004Z]
  {"timestamp":{"epochSecond":1651840129,"nano":4000000}}
  {"timestamp":{"epochSecond":1651840129,"nano":4000000}}

Sample code after version upgrade

pom depedencies

jackson-databind - 2.13.2.1 jackson-datatype-jsr310 - 2.13.2

code changes

just add below lines to the above code

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

output

  Message [source=null, timestamp=2022-05-06T12:28:49.004Z]
  {"timestamp":1651839918.691000000}
  {"timestamp":1.651839918691E9}

Expected output

  Message [source=null, timestamp=2022-05-06T12:28:49.004Z]
  {"timestamp":{"epochSecond":1651840129,"nano":4000000}}
  {"timestamp":{"epochSecond":1651840129,"nano":4000000}}


Solution 1:[1]

I am able to resolve the issue by creating a custom instant serializer and registering it with JavaTimeModule

public class EpochSecondInstantSerializer extends JsonSerializer {

@Override
public Class<Instant> handledType() {
    return Instant.class;
}

@Override
public void serialize(Instant instant, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
    jsonGenerator.writeStartObject();
    jsonGenerator.writeNumberField("epochSecond", instant.getEpochSecond());
    jsonGenerator.writeNumberField("nano", instant.getNano());
    jsonGenerator.writeEndObject();
}

}

then registering with JavaTimeModule ObjectMapper mapper = new ObjectMapper().registerModule( new JavaTimeModule().addSerializer(new EpochSecondInstantSerializer()));

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 StarFish