FasterXML / jackson-dataformats-binary

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

[Ion] Embedded value lost when deserializing with @JsonTypeInfo #152

Open jwhitecl opened 6 years ago

jwhitecl commented 6 years ago

I found an issue when trying to deserialize an IonValue embedded in a pojo. The conditons I've found that are required to hit it:

  1. Must be deserializing to Ion
  2. Must have @JsonTypeInfo annotation on the class (or on a super class) that specifies the type in a property.
  3. The type attribute must come after other attributes of the struct. Anything before the type attribute will be lost during deserialization.

When I've walked through this with a debugger, I found something suspicious happening at this line. I found it was creating a sequence of a json and ion parser and started using the json parser once the type was identified.

This may be related to https://github.com/FasterXML/jackson-dataformats-binary/issues/149 .

Code to reproduce:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import software.amazon.ion.IonSystem;
import software.amazon.ion.IonValue;
import com.fasterxml.jackson.dataformat.ion.ionvalue.IonValueMapper;
import software.amazon.ion.system.IonSystemBuilder;

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        property = "type")
public class Main {
    private IonValue value;

    @JsonCreator
    public Main(@JsonProperty("value") IonValue value) {
        this.value = value;
    }

    public IonValue getValue() {
        return value;
    }

    public static void main(String[] args) throws Exception{
        IonSystem system = IonSystemBuilder.standard().build();
        IonValueMapper mapper = new IonValueMapper(system);

        Main main = mapper.parse(system.singleValue("{value:4.0, type: \"Main\"}"), Main.class);
        System.out.println("newMain value: " + main.getValue()); // prints null, but should be 4.0.
    }
}

Tested with the following dependencies:

    <dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-ion</artifactId>
            <version>2.9.7</version>
        </dependency>
        <dependency>
            <groupId>software.amazon.ion</groupId>
            <artifactId>ion-java</artifactId>
            <version>1.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.7</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.7</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.7</version>
        </dependency>
    </dependencies>