Skip to content

TypeFactory#_fromVariable returns unknownType() even though it has enough information to provide a more specific type #728

@jkochaniak

Description

@jkochaniak

I'm using Jackson 2.2.2 in a Dropwizard service. I'm attempting to create a resource method with a bounded type parameter:

@POST
public <P extends Period> P createPeriod(@PathParam(VERSION_ID) String versionId,
                               P period)

However, when I attempt to post JSON to this endpoint, com.yammer.dropwizard.jersey.JacksonMessageBodyProvider deserializes the request as a LinkedHashMap instead of a Period. I believe there is enough information provided in the method declaration that Jackson should be able to deserialize this correctly. I've traced the problem to the TypeFactory#_fromVariable method.

JacksonMessageBodyProvider extends com.fasterxml.jackson.jaxrs.base.ProviderBase and calls super.readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String,String> httpHeaders, InputStream entityStream) with the following arguments:

type: class Period
genericType: sun.reflect.generics.reflectiveObjects.TypeVariableImpl with name "P"
annotations: []
mediaType: application/json
and the provided headers and stream

This ends up calling the last line in ProviderBase#readFrom:

return reader.withType(genericType).readValue(jp);

ObjectReader#withType eventually calls TypeFactory#constructType(Type type), which passes a null context to _constructType(Type type, TypeBindings context). Since type is an instance of TypeVariable, it ends up calling TypeFactory#_fromVariable(TypeVariable<?> type, TypeBindings context).

Since context is null, this method immediately returns _unknownType(), which means the object ends up deserialized as a LinkedHashMap. However, if I call getBounds() on the type object while in the _fromVariable method, it returns an array containing Period.class. It seems that if we didn't short-circuit due to the null context, _fromVariable would eventually return the right type on the last line: return _constructType(bounds[0], context);

I've searched and couldn't find this exact issue. I looked at the latest code and see the same line, so I don't think upgrading would help.

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