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

Jackson deserializes generic parameter using default deserializer #190

Open
mateuszlitwin opened this issue Sep 11, 2016 · 2 comments
Open

Comments

@mateuszlitwin
Copy link

Here is the test code:

package test;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.io.IOException;
import org.inferred.freebuilder.FreeBuilder;

@FreeBuilder
@JsonDeserialize(builder = GenericType.Builder.class)
interface GenericType<T> {
    T getValue();

    //@JsonCreator
    //static <T> GenericType of(@JsonProperty("value") T value) {
    //    return new GenericType.Builder<>().setValue(value).build();
    //}

    class Builder<T> extends GenericType_Builder<T> {}
}

public class Test {
    public static void main(String[] args) throws IOException {
        String json = "{\"value\": \"123\"}";
        ObjectMapper objectMapper = new ObjectMapper();
        JavaType javaType = objectMapper.getTypeFactory().constructParametricType(
                GenericType.class,
                Long.class);
        GenericType<Long> object = objectMapper.readValue(json, javaType);
        System.out.println(object.getValue().getClass());
    }
}

If you run it, it should result in Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Long.

However changing deserialization from @JsonDeserialize(builder = GenericType.Builder.class) to static @JsonCreator seems to solve the problem, but ideally we don't want to write this manually.

It is worth noting that using String json = "{\"value\": 123}"; result in java.lang.Integer being deserialized instead of java.lang.Long. So it looks like Jackson is picking up some default deserialization method (String for JSON String, Integer for JSON Number) instead of trying to deserialize into custom type. It is especially annoying if you try to use StringWrapper-like classes.

Tested with jackson 2.4.4 and 2.6.5.

@mateuszlitwin mateuszlitwin changed the title Jackson deserializes generic parameter as String Jackson deserializes generic parameter using default deserializer Sep 11, 2016
@mateuszlitwin mateuszlitwin changed the title Jackson deserializes generic parameter using default deserializer Bug? Jackson deserializes generic parameter using default deserializer Sep 11, 2016
@mateuszlitwin mateuszlitwin changed the title Bug? Jackson deserializes generic parameter using default deserializer Jackson deserializes generic parameter using default deserializer Sep 11, 2016
@mateuszlitwin
Copy link
Author

It seems to be caused by FasterXML/jackson-databind#921

I suggest maybe generating @JsonCreator code to fix this issue? It will also get rid of @JsonDeserialize.

@alicederyn
Copy link
Collaborator

Thanks for the investigative work, @divath! I'll leave this as an open "upstream bug" for reference, but I don't think we should be working around open Jackson bugs. (That said, if you release a FreeBuilder fix and commit to maintaining it, that's a different matter 😉 )

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

No branches or pull requests

2 participants