Serialization of Guava optional with polymorphic inner class is not including @class as specified by @JsonTypeInfo
See original GitHub issueDescribe the bug
Serialization of Guava optional with polymorphic inner class is not including @class
as specified by @JsonTypeInfo
It works correctly on Jackson 2.6.5, but stopped working at some point since then. For compatibility reasons our Android app has been locked Jackson 2.6.5 and we only noticed this once server was recently upgrade to 2.13.1 and our integration tests started failing because they use a retrofit client that uses the latest version of jackson.
Version information 2.13.1
To Reproduce Here is the interface
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include= JsonTypeInfo.As.PROPERTY, property="@class")
public interface SourceDevice {
}
Here is the concrete class
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include= JsonTypeInfo.As.PROPERTY, property="@class")
public class AndroidDevice implements SourceDevice {
private final String device;
private final String model;
private final String codename;
private final String brand;
private final String osVersion;
private final String sdkVersion;
private final String product;
private final String deviceId;
private final Map<String, Object> additionalInfo;
@JsonCreator
public AndroidDevice(
@JsonProperty( DEVICE ) String device,
@JsonProperty( MODEL ) String model,
@JsonProperty( CODENAME ) String codename,
@JsonProperty( BRAND ) String brand,
@JsonProperty( OS_VERSION ) String osVersion,
@JsonProperty( SDK_VERSION ) String sdkVersion,
@JsonProperty( PRODUCT ) String product,
@JsonProperty( DEVICE_ID ) String deviceId,
@JsonProperty( ADDITIONAL_INFO ) Optional<Map<String, Object>> additionalInfo ) {
this.device = device;
this.model = model;
this.codename = codename;
this.brand = brand;
this.osVersion=osVersion;
this.sdkVersion = sdkVersion;
this.product = product;
this.deviceId = deviceId;
this.additionalInfo = additionalInfo.or( HashMap::new );
}
}
The setup for the object mapper:
mapper.registerModule( new GuavaModule() );
mapper.registerModule( new JodaModule() );
mapper.configure( SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false );
Our actual serialization test is here: https://github.com/openlattice/chronicle-server/blob/18be3bfc845445e20b3fdc1094c5e8194d49c1ae/src/test/kotlin/com/openlattice/chronicle/serialization/SourceDeviceSerializationTest.kt
Base serialization test class is here: https://github.com/geekbeast/rhizome-client/blob/da2c8807fc4b8fa085375a58502db47baa6f36fb/src/test/java/com/geekbeast/serializer/serializer/AbstractJacksonSerializationTest.java
Expected behavior Expected behavior is the following json string:
{"@class":"com.openlattice.chronicle.sources.AndroidDevice","device":"650ad51cf4a84729","model":"Android SDK built for x86","codename":"REL","brand":"Android","osVersion":"30","sdkVersion":"30","product":"sdk_phone_x86","deviceId":"650ad51cf4a84729","additionalInfo":{}}
Instead here is what is serialized:
{"device":"650ad51cf4a84729","model":"Android SDK built for x86","codename":"REL","brand":"Android","osVersion":"30","sdkVersion":"30","product":"sdk_phone_x86","deviceId":"650ad51cf4a84729","additionalInfo":{}}
Issue Analytics
- State:
- Created 2 years ago
- Comments:9 (5 by maintainers)
Top GitHub Comments
While I won’t yet close this issue, I think that the eventual evaluation will be that of later Jackson versions working as expected; while 2.6 did work the way that was good in your case it is unfortunately incompatible with the way polymorphic handling overall works.
2.7+ handling can be made to work with polymorphic contents of
Optional
s as suggested by above changes, however.Ok good @geekbeast thank you for the update. It is good that you can work around this problem. It is unfortunate there is this discontinuity, but supporting
Optional
has been challenging as there are (at least) 2 ways to go about it. And initial implementation did not fully consider polymorphic handling of contents either.