FasterXML / jackson-modules-java8

Set of support modules for Java 8 datatypes (Optionals, date/time) and features (parameter names)
Apache License 2.0
398 stars 116 forks source link

`OffsetDateTime`deserialization fails when using (specific?) date-time pattern #279

Open cristibozga opened 1 year ago

cristibozga commented 1 year ago

If we have an OffsetDateTime property inside a DTO where we specify the pattern, the deserialization operation fails: Ex: Inside OffsetDateDto:

   private OffsetDateTime date= OffsetDateTime.now(ZoneId.of("UTC")).truncatedTo(ChronoUnit.SECONDS);

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
    public OffsetDateTime getDate() {
        return date;
    }
    public void setDate(OffsetDateTime date) {
        this.date = date;
    }

The code of the application:

           ObjectMapper o = new ObjectMapper();
            o.findAndRegisterModules();
            OffsetDateDto dto = new OffsetDateDto();
            StringWriter w = new StringWriter();
            o.writeValue(w, dto);
            String s = w.toString();
            System.out.println(s);
            OffsetDateDto x = o.readValue(s.getBytes(StandardCharsets.UTF_8), OffsetDateDto.class);

When we write the value (serialize dto I get displayed: '{"date":"2023-09-01T11:07:48Z",...'} But the last line throws an error because deserialization fails:

com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.OffsetDateTime` from String "2023-09-01T11:07:48Z": Failed to deserialize java.time.OffsetDateTime: (java.time.DateTimeException) Unable to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2023-09-01T11:07:48 of type java.time.format.Parsed
 at [Source: (byte[])"{"date":"2023-09-01T11:07:48Z","localDate":"2023-09-01","localDateTime":"2023-09-01T11:07:48.7458067"}"; line: 1, column: 9] (through reference chain: json.OffsetDateDto["date"])
    at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67)
    at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:1991)
    at com.fasterxml.jackson.databind.DeserializationContext.handleWeirdStringValue(DeserializationContext.java:1219)
    at com.fasterxml.jackson.datatype.jsr310.deser.JSR310DeserializerBase._handleDateTimeException(JSR310DeserializerBase.java:176)
    at com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer._fromString(InstantDeserializer.java:307)
    at com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer.deserialize(InstantDeserializer.java:217)
    at com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer.deserialize(InstantDeserializer.java:51)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:313)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:176)
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4674)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3690)
    at json.JsonObjectMapperTester.testOffsetDate(JsonObjectMapperTester.java:60)
    at a.Starter.main(Starter.java:21)
Caused by: java.time.DateTimeException: Unable to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2023-09-01T11:07:48 of type java.time.format.Parsed
    at java.base/java.time.OffsetDateTime.from(OffsetDateTime.java:372)
    at com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer._fromString(InstantDeserializer.java:302)
    ... 10 more
Caused by: java.time.DateTimeException: Unable to obtain ZoneOffset from TemporalAccessor: {},ISO resolved to 2023-09-01T11:07:48 of type java.time.format.Parsed
    at java.base/java.time.ZoneOffset.from(ZoneOffset.java:350)
    at java.base/java.time.OffsetDateTime.from(OffsetDateTime.java:361)
    ... 11 more

I've tried also with the pattern 'yyyy-MM-dd'T'HH:mm:ssX' and I get the same error. Am I doing something wrong here?

Thanks in advance

phoebe-lew commented 11 months ago

Had the same issue and fixed it by updating the pattern to "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", but did not dig into why "yyyy-MM-dd'T'HH:mm:ss'Z'" doesn't work when OffsetDateTime.parse() is fine with a string in the yyyy-MM-dd'T'HH:mm:ss'Z' format.

jaymanik commented 1 month ago

I faced error similar to what is posted above, when I upgraded lombok from '1.18.12' to '1.18.30'. In my project, Tests which were working fine earlier started failing with deserialization error after the lombok version upgrade. Error fixed itself when I downgraded back the lombok version.

So, I think this has something to do with one of the transitive dependencies not being compatible.

Jdk 8 Azul Zulu Jackson2:2.10.1 library version jackson-annotations component

cowtowncoder commented 1 month ago

Including JDK version for failing case would be useful as well. And obviously Jackson versions (plus need to ensure Jackson versions of components are aligned).

Lombok version discrepancy sounds odd, but could be due to Lombok's changing Jackson annotations it adds.

jaymanik commented 1 month ago

Including JDK version for failing case would be useful as well. And obviously Jackson versions (plus need to ensure Jackson versions of components are aligned).

Lombok version discrepancy sounds odd, but could be due to Lombok's changing Jackson annotations it adds.

Added details in my original comment. What I could not understand is that before and after Lombok upgrade, Jackson2 library version was same.

cowtowncoder commented 1 month ago

@jaymanik Jackson 2.10 is very old version, as the latest is 2.17.2. So I would try out version upgrade first.

But I also realized that the original issue did not refer to Lombok so not sure if @jaymanik 's problem is same as @cristibozga's.

jaymanik commented 1 month ago

@jaymanik Jackson 2.10 is very old version, as the latest is 2.17.2. So I would try out version upgrade first.

But I also realized that the original issue did not refer to Lombok so not sure if @jaymanik 's problem is same as @cristibozga's.

Thank you for your suggestion. I will try to upgrade jackson2 and give it a try.

Apologies for not sharing stack trace. We are not allowed to add GitHub comments from my work machine.

cristibozga commented 1 month ago

Sorry for missing some important data. So: Jackson version is 2.13.5 JDK version is 17

Including JDK version for failing case would be useful as well. And obviously Jackson versions (plus need to ensure Jackson versions of components are aligned).

Lombok version discrepancy sounds odd, but could be due to Lombok's changing Jackson annotations it adds.

cowtowncoder commented 1 month ago

Jackson 2.13 is still old enough version that it'd definitely make sense to try with 2.17(.2) just rule out possibility of a fix.

cowtowncoder commented 2 weeks ago

Ok; verified the issue exists in 2.18 branch; added failing test as well -- don't have time to look deeper but hopefully this helps whoever decides to work on it.