Skip to content

Jackson 2.6.x -> 2.7 deserialize generic fails when calling Spring controller [SPR-14470] #19039

Closed
@spring-projects-issues

Description

@spring-projects-issues

Wagner Michael opened SPR-14470 and commented

I'm just trying to upgrade (Spring 4.3 project) from jackson 2.6.3 to 2.7 and getting an error.

This is my simplyfied project:

Abstract controller class with a http post method which accepts a requestBody of a generic list:

public abstract class AbstractController<T extends Entity> {

    @RequestMapping(value = "/", method = POST)
    public void method1(@RequestBody final List<T> entities){
        System.out.println("AbstractController called");
    }
}

Controller implementation with a simple Entity class

@RestController
@RequestMapping("/impl1")
public class ControllerImpl extends AbstractController<EntityImpl> {
}

second controller with method1 overriden

@RestController
@RequestMapping("/impl2")
public class ControllerImpl2 extends AbstractController<EntityImpl2> {

    @Override
    public void method1(@RequestBody List<EntityImpl2> entities) {
        System.out.println("ControllerImpl2 called");
    }
}

My Entity:

public class EntityImpl implements Entity<Integer> {

    private String name;

    public EntityImpl() {
    }

    public EntityImpl(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(final String name) {
        this.name = name;
    }
}

Ok, so this setup works fine with Jackson 2.6.x and Spring 4.2.x, but i need to upgrade to at least 2.7.
But with 2.7 every post request to "/impl1/" gives me this error:

Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Can not construct instance of jackson.entity.Entity, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
     at [Source: java.io.PushbackInputStream@1aa5c56a; line: 1, column: 2] (through reference chain: java.util.ArrayList[0]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of jackson.entity.Entity, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
     at [Source: java.io.PushbackInputStream@1aa5c56a; line: 1, column: 2] (through reference chain: java.util.ArrayList[0])

Thought posts to /impl2/ workwith both versions ... but i really dont want to override every method there.

Is there a way to solve this?
I have created a sample project with some pretty easy tests showing this behavior.
Just run

./gradlew build

If you open gradle.build and remove these lines:

// uncomment both for failing tests!!
    compile "com.fasterxml.jackson.core:jackson-databind:2.7.0"
    compile "org.springframework:spring-webmvc:4.3.0.RELEASE"

Tests are working fine then. (Jackson 2.6 and Spring 4.2 are being used then).
Am i missing any configuration there, which was not needed prior jackson 2.7?

Hope someone can help me here :)


Affects: 4.3.1

Attachments:

Issue Links:

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions