-
-
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
TypeFactory
type resolution broken in 2.7 for generic types when using constructType
with context
#1456
Comments
@Spikhalskiy unfortunately usage in the test is not quite how type resolution is designed to work: all method/field types must be resolved by starting with class (or parameterized type) that contains them, and only this resolution is designed to produce proper type bindings. There are two possibilities here:
I can try modified version just to verify which way it goes. In case (2) this obviously should be fixed; but (1) is more difficult and there's no guarantee. If it may still be fixed that'd be good of course. Just that there may be separate issues. |
@cowtowncoder Problem is here https://github.com/spring-projects/spring-framework/blob/4.0.x/spring-web/src/main/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverter.java#L281 So, if implement the same controllers structure as described in this topic using Spring controllers - This version is not EOL. And more modern versions have same code actually: https://github.com/spring-projects/spring-framework/blob/4.1.x/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java#L278 So, Spring relies on this specific method behavior and behavior changed in 2.7.x branch. Read your answer mostly as "now thing works as designed", sorry for too many questions if instead, you think it should be fixed to work with Spring correctly. |
Provide a failing test for the issue #1456
… when resolved through enclosing class
@Spikhalskiy Ok, I added another test method to ensure that type resolution itself works correctly; it does. Now, let me first explain what is happening, and why result does not work. JavaType contextType = MAPPER.constructType(ImplController.class);
// actually declared in base type so...
contextType = contextType.getSuperClass();
JavaType resolvedType = MAPPER.getTypeFactory().constructType(entityType, contextType); and this gives the expected answer, as So why did this work in 2.6 and earlier? Because back then, With that explanation, let me re-read your comment to see what could be done here. :) |
@Spikhalskiy Ok. Yes, I understand that breakage in behavior is unfortunate and not Spring's fault. Unfortunately rewrite of type resolution system was difficult and not entirely painless. On plus side it did fix a few long-lived bugs related to type aliasing; on downside there are some usages that can not be supported exactly as is. Now... conceptually, what is needed is to find the I don't know if there is enough information to do that; this is problem with many frameworks. Unfortunately One other alternative that I can play with a bit is to see if -- just for these two deprecated methods -- it'd be possible and reasonable to see if one of parent types have non-empty |
TypeFactory
type resolution broken in 2.7 for generic types when using constructType
with context
@Spikhalskiy Ok. I think hack I added for 2.7.9 / 2.8.6 should help a lot. Going forward new code really should not use these methods, but methods themselves are simple enough to keep until 3.0. Not sure what should be done at that point, since these methods can not be made to work much better (as per earlier explanation), but at the same time since many/most(/all?) Java web service frameworks still pass incomplete information despite it being a well-known issue this is insufficient. Given this maybe such methods are still necessary... Anyway: thank you again for all your help! |
@cowtowncoder Thanks a lot for the fix, Tatu! Will check nightly build when get a chance, if the old spring behavior is back. Yep, would be great to keep it until the major release when Spring team will revisit/reimplement integration. |
@Spikhalskiy yea. It might be worth seeing if the work-around I added might be done by caller instead, because that way previously released 2.7.x / 2.8.x versions would also work. Logic is pretty simple; if |
Hi,
Spring uses TypeFactory#constructType to resolve entity class to deserialize into in case of controllers inheritance with Generics on base classes.
I made simplified version and localized issue in provided simple test, which is a naive simulation of what's Spring does.
This test is broken in 2.7.x, 2.8.x, master. Works fine in 2.5.x and 2.6.x.
So, since 2.7 resolvedType.getRawClass() contains BaseEntity.class, which is incorrect with the provided context.
The text was updated successfully, but these errors were encountered: