Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
jkochaniak opened this issue Mar 19, 2015 · 4 comments
Milestone

Comments

@jkochaniak
Copy link

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.

@cowtowncoder
Copy link
Member

Thanks, it does sounds like a bug. There are many problems with type handling, and some relate to missing information passed by JAX-RS, but in this case it does seem like bounds ought to be availble for use, since it is a local declaration

@cowtowncoder
Copy link
Member

Hmmh. This is interesting... type-erased type would actually resolve correctly, and the problem is just with generic type. Anyway, I can resolve this locally, hope to fix it soon.

@cowtowncoder cowtowncoder modified the milestones: 1.9.13, 2.5.2 Mar 20, 2015
@cowtowncoder
Copy link
Member

Turned out to be relatively easy to fix. And also helped resolve #609, awesome (and somewhat) synergy at play. Thank you again for reporting this! Fix will be in 2.5.2.

@jkochaniak
Copy link
Author

Awesome, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants