Skip to content

SimpleAbstractTypeResolver breaks generic parameters #1186

@tobiash

Description

@tobiash

Upgrading to Jackson 2.7.3 breaks generic parameters for me when using an abstract type mapping.
I'm not sure if this is related to #1173, but I'm not using any raw types here. I was able to create a simple test case that seems very similiar to the examples given in the comments of SimpleAbstractTypeResolver, yet it doesn't work:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.junit.Test;

import java.io.IOException;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class AbstractTypeMappingGenericsProblemTest {

    public interface IContainer<T> {
        @JsonProperty("ts")
        List<T> getTs();
    }

    public static class MyContainer<T> implements IContainer<T> {

        final List<T> ts;

        @JsonCreator
        public MyContainer(@JsonProperty("ts") List<T> ts) {
            this.ts = ts;
        }

        public List<T> getTs() {
            return ts;
        }
    }

    public static class MyObject {
        @JsonProperty("msg")
        String msg;
    }


    @Test
    public void testDeserializeMyContainer() throws IOException {
        Module module = new SimpleModule().addAbstractTypeMapping(IContainer.class, MyContainer.class);
        final ObjectMapper mapper = new ObjectMapper().registerModule(module);
        String json = "{\"ts\": [ { \"msg\": \"hello\"} ] }";
        final Object o = mapper.readValue(json, mapper.getTypeFactory().constructParametricType(IContainer.class, MyObject.class));
        assertThat(o, instanceOf(MyContainer.class));
        assertThat(o, hasProperty("ts", contains(instanceOf(MyObject.class))));
    }

}

I am able to make the test case work using a custom implementation of AbstractTypeResolver that directly resolves to a parameterized type:

        Module module = new Module() {

            // ....

            @Override
            public void setupModule(SetupContext context) {
                context.addAbstractTypeResolver(new AbstractTypeResolver() {
                    @Override
                    public JavaType findTypeMapping(DeserializationConfig config, JavaType type) {
                        //  Just a simple stub implementation
                        if (type.getRawClass().equals(IContainer.class)) {
                            return config.getTypeFactory().constructParametricType(MyContainer.class, MyObject.class);
                        }
                        return super.findTypeMapping(config, type);
                    }
                });
            }
        };

So is this a bug or does SimpleAbstractTypeResolver just not really support generics? Or did I misunderstand something here? Is implementing a custom AbstractTypeResolver the way to go?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions