-
Notifications
You must be signed in to change notification settings - Fork 83
Description
Suppose a class hierarchy like this:
public record Record(Field field) {
}
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="@class")
@JsonSubTypes({
@JsonSubTypes.Type(value = StringField.class, name = "string"),
@JsonSubTypes.Type(value = IntField.class, name = "int")
})
public abstract class Field {
}
public class StringField extends Field {
private final String val;
@JsonCreator
public StringField(@JsonProperty("val") String val) {
this.val = val;
}
public String getVal() {
return val;
}
}
public class IntField extends Field {
private final int val;
@JsonCreator
public IntField(@JsonProperty("val") int val) {
this.val = val;
}
public int getVal() {
return val;
}
}
Using Jackson on standard desktop Java SE, the following code works as expected:
String serialized = new ObjectMapper().writeValueAsString(r);
new ObjectMapper().readValue(serialized, Record.class);
However, that is not the case on Android (using the AndroidRecordModule), where the deserializer is oblivious of all class annotations (and, consequently, the JsonTypeInfo), and thus is unable to deserialize the abstract type Field
. (abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
)
I would presume that the issue lies within this code:
Line 153 in 9b2fe00
null, null, parameter.getAllAnnotations(), parameter, i, injectable, null); |
Field
.
My current workaround is to wrap objects akin to Field
in this example into the following:
public class ContainerObject<T> { //Android Studio's opinion of this code is "Class can be converted to record class". Well, if only I could:)
public final T value;
@JsonCreator
public ContainerObject(@JsonProperty("value") T value) {
this.value = value;
}
}
and then change Record
to be
public record Record(ContainerObject<Field> field) {
}
Using this wrapper, deserialization works as expected on Android. However, the general issue seems to be a bug within Jackson's AndroidRecordModule.
If so desired, I'm willing to fix this myself and PR it.