FasterXML / jackson-dataformat-xml

Extension for Jackson JSON processor that adds support for serializing POJOs as XML (and deserializing from XML) as an alternative to JSON
Apache License 2.0
561 stars 221 forks source link

Kotlin: XmlMapper is not calling custom LocalDateTime serializer for JavaTimeModule #581

Open martbab opened 1 year ago

martbab commented 1 year ago

NOTE: may be duplicate of https://github.com/FasterXML/jackson-dataformat-xml/issues/41.

Description:

In one of our projects we use XmlMapper to deserialize third-party XML to beans containing LocalDateTime instances. The XML stores local date and time in the configured timezone, and during deserialization we have a custom subclass of com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer which converts it to LocalDateTime value in UTC (which is a requirement of our system).

When implementing the inverse operation (serializing bean to XML conforming to third-party spec), I first implemented the custom subclass of com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer doing the inverse conversion, so from UTC LocalDateTime to the LocalDateTime of configured timezone.

Both of them are registered as deserializer/serialized for LocalDateTime type in com.fasterxml.jackson.datatype.jsr310.JavaTimeModule instance.

During deserialization, I can verify that our custom implementation is called, but the inverse operation skips custom serializer and falls back to default com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer every time.

This then forces me work around this by implementing serializer for the whole bean type, and do the conversion there.

Because the stuff is quite hard to explain, I have implemented a simple reproducer which you can clone and run included tests.

Steps to reproduce:

Library versions:

com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.14.2 com.fasterxml.jackson.module:jackson-module-kotlin:2.14.2 com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.2

Steps to reproduce:

Build the reproducer from this repo and run included tests.

Expected outcome:

All tests pass because registration of both custom serializer and deserializer of LocalDateTime type works.

Actual outcome:

Tests fail, with failures indicating that the built-in JSR310 LocalDateTime serializer is not overriden by custom one.

pjfanning commented 1 year ago

Might be better to provide an actual java test case. Essays about issues can be misinterpreted and some times the essays turn out to be an incorrect summary.

martbab commented 1 year ago

Hello I filled in a repo with a test case which I created here: https://github.com/martbab/jackson-dataformat-xml-issue-581-reproducer

cowtowncoder commented 1 year ago

Without knowing about details (and not having to dig deep), one thing I'd suggest is that in case of multiple modules registering a serializer/deserializer, later registration "wins"; so it may come down to making sure your custom (de)serializers are registered after JSR310 ones. XML module doesn't have overrides for (de)serializers so that shouldn't matter.