Skip to content

jackson-dataformat-ion does not handle null.struct deserialization correctly #295

@MartinGian

Description

@MartinGian

Hi there,

Jackson-dataformat-ion 2.12 is not handling null deserialization correctly.

Here is the test:

import com.amazon.ion.IonSystem;
import com.amazon.ion.IonValue;
import com.amazon.ion.system.IonSystemBuilder;

@Test
public void shouldBeAbleToSerializeAndDeserializeNullStructs() throws Exception {
    // given
    IonSystem ionSystem = IonSystemBuilder.standard().build();
    IonObjectMapper mapper = new IonValueMapper(ionSystem)
            .configure(IonGenerator.Feature.USE_NATIVE_TYPE_ID, false)
            .configure(IonParser.Feature.USE_NATIVE_TYPE_ID, false);

    // when
    IonValue nullStruct = ionSystem.newNullStruct();
    IonValue ionValue = mapper.writeValueAsIonValue(nullStruct);

    // then
    IonValue parsedValue = mapper.readValue(ionValue, IonValue.class);
    assertThat(parsedValue, equalTo(nullStruct));
}

java.lang.AssertionError: 
Expected: <null.struct>
     but: was null
Expected :<null.struct>
Actual   :null

As you can see, it is deserializing null.struct into a Java null instead of deserializing it to an IonValue containing a null struct. This leads to NullPointerException and furthermore, IMO is losing data as a null struct is not the same as a Java null. It also loses any annotation that the null.struct may have, example: IonValue nullStruct = ionSystem.singleValue("foo::null.struct");, this is read by the mapper as a Java null as well.

The serialization works correctly, it is the deserialization that is not parsing this null values correctly.

Playing a bit with it, if you change the implementation of IonValueDeserializer and add the following override, the test above passes.

@Override
public IonValue getNullValue(DeserializationContext ctxt) throws JsonMappingException {
    try {
        return deserialize(ctxt.getParser(), ctxt);
    } catch (IOException e) {
        throw new JsonMappingException(e.getMessage());
    }
}

It would be great if someone with more experience with Jackson can validate this. I'm happy to create a PR with the change if someone from your team confirms that this is the correct implementation.

Regards.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions