-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
SimpleAbstractTypeResolver breaks generic parameters #1186
Comments
From quick look your usage seems valid, and there certainly should not be need for custom resolver. |
Sorry, forgot to mention this: The list contains instances of mapper.readValue(json, mapper.getTypeFactory().constructParametricType(MyContainer.class, MyObject.class)) // List gets filled with MyObject instances |
Found a similar problem with deserializing parameterized interfaces: private static class MyList {
@JsonProperty("strings")
List<String> strings;
@JsonCreator
MyList(@JsonProperty("strings") String... strings) {
this.strings = Arrays.asList(strings);
}
} // MyList
@JsonDeserialize(as = HolderImpl.class)
private static interface Holder<S> {
S getData();
} // Holder
private static class HolderImpl<S> implements Holder<S> {
private final S data;
@JsonCreator
HolderImpl(@JsonProperty("stuff") S data) {
this.data = data;
}
@JsonProperty("stuff")
@Override
public S getData() {
return data;
}
} // HolderImpl
public boolean isOk() throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
Holder<MyList> h = new HolderImpl<MyList>(new MyList("Hydrogen", "Helium"));
String json = mapper.writeValueAsString(h);
Holder<MyList> parsed = mapper.readValue(json, new TypeReference<Holder<MyList>>() { });
return parsed.getData() instanceof MyList;
} Using 2.6.x the A co-worker adds: In 2.6.3 when the In 2.7.0, in the same general area, if (baseType.isInterface()) {
newType = baseType.refine(subclass, TypeBindings.emptyBindings(), null,
new JavaType[] { baseType });
} else {
newType = baseType.refine(subclass, TypeBindings.emptyBindings(), baseType,
NO_TYPES);
}
// Only SimpleType returns null, but if so just resolve regularly
if (newType == null) {
// But otherwise gets bit tricky, as we need to partially resolve the type hierarchy
// (hopefully passing null Class for root is ok)
newType = _fromClass(null, subclass, TypeBindings.emptyBindings());
} .... which just returns null for |
Ok, I can reproduce this with 2.7, and it is also present in I'll see if I can solve this case: I am pretty sure this does not affect (more) common cases of |
Ok. How would a fix work? Implement an AbstractTypeResolver that basically does what my workaround implementation does, but for the general case, tracking generic variables through the hierarchy? |
@tobiash In general since you know type bindings, you can explicitly construct subtypes using Full fix will be in |
Ok. I figured out a way to fix usage along this common pattern, and although it is not as generic as I wish (in fact it would suffer from reordering of parameters, or partial binding; although not from aliasing-by-name), I think it should go a long way towards fixing regressions from 2.6. |
Upgrading to Jackson 2.7.3 breaks generic parameters for me when using an abstract type mapping.
I'm not sure if this is related to #1173, but I'm not using any raw types here. I was able to create a simple test case that seems very similiar to the examples given in the comments of SimpleAbstractTypeResolver, yet it doesn't work:
I am able to make the test case work using a custom implementation of AbstractTypeResolver that directly resolves to a parameterized type:
So is this a bug or does SimpleAbstractTypeResolver just not really support generics? Or did I misunderstand something here? Is implementing a custom AbstractTypeResolver the way to go?
The text was updated successfully, but these errors were encountered: