FasterXML / jackson-dataformats-binary

Uber-project for standard Jackson binary format backends: avro, cbor, ion, protobuf, smile
Apache License 2.0
310 stars 133 forks source link

Ion Polymorphic deserialization in 2.12 breaks wrt use of Native Type Ids when upgrading from 2.8 #270

Open manaigrn-amzn opened 3 years ago

manaigrn-amzn commented 3 years ago

Given the following classes:

    @JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "base",
        visible = true
    )
    @JsonSubTypes({
        @Type(value = Subclass.class, name = "subclass"),
    })
    static public class BaseClass {
    }

    public static class Subclass extends BaseClass {
        public String base;
    }

    public static class Container {
        public BaseClass objectWithType;
    }

The following ion can be deserialized using Jackson-dataformat-ion 2.8:

{
    objectWithType:type::{
        base: "subclass"
        name: "Some name"
    } 
}

Current Behavior

When using Jackson-dataformat-ion 2.12.x, the following exception is thrown:

com.fasterxml.jackson.databind.exc.InvalidTypeIdException:
Could not resolve type id 'type' as a subtype of `com.fasterxml.jackson.dataformat.ion.polymorphism.PolymorphicTypeAnnotationsTest$BaseClass`: known type ids = [PolymorphicTypeAnnotationsTest$BaseClass, subtype] (for POJO property 'objectWithType')

This happens because IonParser.canReadTypeId() always returns true, it makes Jackson-databind incorrectly read the field name token type:: as a native type id.

Expected Behavior

There should not be an exception. This could be accomplished by allowing the check for native type ids to be disabled in the IonParser while deserializing, similar to what was added in the IonGenerator in #232 during serialization.

Then, the IonMapper could be configured with the following:

IonObjectMapper ionMapper = new IonValueMapper();
ionMapper.disable(IonParser.Feature.USE_NATIVE_TYPE_ID)

Note: disabling IonGenerator.Feature.USE_NATIVE_TYPE_ID (which is already available) doesn't do the trick here.

cowtowncoder commented 3 years ago

Solved by addition of:

IonParser.Feature.USE_NATIVE_TYPE_ID