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

Materialized generic class resolved incorrectly #188

Open
shmosel opened this issue Nov 25, 2022 · 2 comments
Open

Materialized generic class resolved incorrectly #188

shmosel opened this issue Nov 25, 2022 · 2 comments
Labels
mrbean pr-welcome Issue for which progress most likely if someone submits a Pull Request

Comments

@shmosel
Copy link

shmosel commented Nov 25, 2022

When a generic interface is materialized with varying type parameters, it seems to confuse one for the other:

public static void main(String[] args) throws Exception {
    ObjectMapper mapper = new ObjectMapper()
            .registerModule(new MrBeanModule());

    mapper.readValue("{\"a\":{\"x\":\"1\"},\"b\":{\"x\":\"B\"}}", Outer.class);
}

public static class Outer {
    public Inner<Integer> a;
    public Inner<String> b;
}

public interface Inner<T> {
    T getX();
}

Output:

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.lang.Integer` from String "B": not a valid `java.lang.Integer` value
 at [Source: (String)"{"a":{"x":"1"},"b":{"x":"B"}}"; line: 1, column: 25] (through reference chain: Scratch$Outer["b"]->com.fasterxml.jackson.module.mrbean.generated.Scratch$Inner["x"])
	at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67)
	at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:1991)
	at com.fasterxml.jackson.databind.DeserializationContext.handleWeirdStringValue(DeserializationContext.java:1219)
	at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseInteger(StdDeserializer.java:840)
	at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseInteger(StdDeserializer.java:820)
	at com.fasterxml.jackson.databind.deser.std.NumberDeserializers$IntegerDeserializer.deserialize(NumberDeserializers.java:531)
	at com.fasterxml.jackson.databind.deser.std.NumberDeserializers$IntegerDeserializer.deserialize(NumberDeserializers.java:506)
	at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:314)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
	at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:314)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4674)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3629)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3597)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
	at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:314)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4674)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3629)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3597)

Why does it think b.x should be an Integer?

@cowtowncoder
Copy link
Member

I assume this is for Mr Bean module?

@cowtowncoder
Copy link
Member

Correct: mr Bean cannot materialize generic types (ones with type parameters) in a way that generics are retained.
What probably happens is that the class being generated uses bindings of the first resolved type being passed: this will then have "correct" type bindings for that first type but not for others.

I wonder if module should rather throw an exception if encountering such case.
Or, alternatively, just not generate anything and let this case work the way it will (throwing exception unless something else materializes type).

Ideally it would of course create declarations that retain type parameter references.
But I don't think I'll have time to dig into this myself. Maybe someone else would tho.

@cowtowncoder cowtowncoder added the pr-welcome Issue for which progress most likely if someone submits a Pull Request label Nov 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mrbean pr-welcome Issue for which progress most likely if someone submits a Pull Request
Projects
None yet
Development

No branches or pull requests

2 participants