-
-
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
Rewrite Bean Property Introspection logic in Jackson 2.x #4515
Comments
Started reading the code and clearly more of code wrt Creator detection needs to move from But not sure whether to try to move abstractions from Factory part, or rewrite; and whether to try move things incrementally or not. Started removing deprecated methods from code paths, to help isolate actual in-use code. |
If we agree that we have enough test coverage, I guess.... rewrite, move big-step-incrementally? |
@JooHyukKim Yes, I think test coverage is sufficient to allow refactoring. I am struggling at finding the steps tho. Especially in a way that would allow merging 2.18 -> master. And one problem part is that the latest |
Ok one big challenge that is coming up now, looking through functionality in In the meantime I am making small incremental changes, including removal of deprecated code in affected areas. |
Right. Also from my experience, many times it was necessary to both modify existing and add additional "internal" structure to make the code base in better shape. More of "tidy up just before making changes". Just out of curiosity, are we going to introduce |
Not planned yet. I am thinking it should be possible to make things work without fully separate implementation. But of course if it becomes necessary that could be done. At this first I would really want to make existing logic work same as now, but get Creator properties discovered around time others are... so move it out of |
Hmmmh. Despite incremental refactoring, I don't think functional from ... Ok. So, in |
Good progress:
Hoping to solve remaining Record tests, to get first PR merged into 2.18, then master. |
First part of refactoring towards #4515.
Forgot to add an update: #4532 was merged 2 days ago, and it handles front-end half of changes:
I also started to look into the second half (reducing/removing code from |
Ok some more progress: now But quite a bit remains to rewrite in |
@JooHyukKim one quick note: while fixing issues with jackson-databind/3.0, I backported them into 2.x -- basically these are uncovered in 3.0 since it included parameter names module (unlike 2.x where it is separate). So there's a slight chance that something wrt Kotlin could be fixed by these changes. |
access=READ_ONLY
#4119
Kotlin module still failing. So I filed a PR moving the test to failing FasterXML/jackson-module-kotlin#802. |
Hi, just to confirm after release |
@StefanBratanov Probably. You are free to test ur case against Jackson 2.18 👍🏼. In case it doesn't, let us know |
@StefanBratanov I think your use case is already supported since |
…legating JsonCreator The refactor to bean property introspection in FasterXML#4515 caused existing no-arg delegatring constructors to fail deserialization. Example from this branch where we test RC releases: palantir/conjure-java#2349 specifically this test: https://github.com/palantir/conjure-java/blob/19d7f54eb0001c49b5d8a4bb897b9ad4cb5a28de/conjure-java-core/src/test/java/com/palantir/conjure/java/types/NoFieldBeanTests.java#L36-L39 Using this type: https://github.com/palantir/conjure-java/blob/19d7f54eb0001c49b5d8a4bb897b9ad4cb5a28de/conjure-java-core/src/integrationInput/java/com/palantir/product/EmptyObjectExample.java ``` InvalidDefinitionException: Invalid type definition for type `com.palantir.product.EmptyObjectExample`: No argument left as delegating for Creator [method com.palantir.product.EmptyObjectExample#of()]: exactly one required at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 1] at app//com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:62) at app//com.fasterxml.jackson.databind.DeserializationContext.reportBadTypeDefinition(DeserializationContext.java:1866) at app//com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._addExplicitDelegatingCreator(BasicDeserializerFactory.java:489) at app//com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._addExplicitDelegatingCreators(BasicDeserializerFactory.java:365) at app//com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._constructDefaultValueInstantiator(BasicDeserializerFactory.java:270) at app//com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator(BasicDeserializerFactory.java:219) at app//com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:262) at app//com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:151) at app//com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:471) at app//com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:415) at app//com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:317) at app//com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:284) at app//com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:174) at app//com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:669) at app//com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:5048) at app//com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4918) at app//com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3860) at app//com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3828) at app//com.palantir.conjure.java.types.NoFieldBeanTests.testDeserializeUsesSingleton(NoFieldBeanTests.java:38) ``` It's not entirely clear that we are correctly using the `DELEGATING` type here, perhaps the `PROPERTIES` type would be a better fit, however neither necessarily document support for a no-arg constructor. In general we prefer `DELEGATING` when possible to avoid ambiguity with potential property sources -- we want the ability to fail deserialization in this case when any properties are included in the incoming object. In 2.17.2, this branch allowed the code to functiona as we desired: https://github.com/FasterXML/jackson-databind/blob/091d968751ef00150d22a788fe7f45b7cdcb337a/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java#L658-L662 Is there any chance we could allow the previous DELEGATING behavior to continue to handle the no-arg case? If we'd prefer to move away from `DELEGATING` for that case, is there any chance we could emit a deprecation warning for some time? I've included a potential patch which recovers the previous behavior.
…legating JsonCreator The refactor to bean property introspection in FasterXML#4515 caused existing no-arg delegatring constructors to fail deserialization. Example from this branch where we test RC releases: palantir/conjure-java#2349 specifically this test: https://github.com/palantir/conjure-java/blob/19d7f54eb0001c49b5d8a4bb897b9ad4cb5a28de/conjure-java-core/src/test/java/com/palantir/conjure/java/types/NoFieldBeanTests.java#L36-L39 Using this type: https://github.com/palantir/conjure-java/blob/19d7f54eb0001c49b5d8a4bb897b9ad4cb5a28de/conjure-java-core/src/integrationInput/java/com/palantir/product/EmptyObjectExample.java ``` InvalidDefinitionException: Invalid type definition for type `com.palantir.product.EmptyObjectExample`: No argument left as delegating for Creator [method com.palantir.product.EmptyObjectExample#of()]: exactly one required at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 1] at app//com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:62) at app//com.fasterxml.jackson.databind.DeserializationContext.reportBadTypeDefinition(DeserializationContext.java:1866) at app//com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._addExplicitDelegatingCreator(BasicDeserializerFactory.java:489) at app//com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._addExplicitDelegatingCreators(BasicDeserializerFactory.java:365) at app//com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._constructDefaultValueInstantiator(BasicDeserializerFactory.java:270) at app//com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator(BasicDeserializerFactory.java:219) at app//com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:262) at app//com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:151) at app//com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:471) at app//com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:415) at app//com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:317) at app//com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:284) at app//com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:174) at app//com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:669) at app//com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:5048) at app//com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4918) at app//com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3860) at app//com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3828) at app//com.palantir.conjure.java.types.NoFieldBeanTests.testDeserializeUsesSingleton(NoFieldBeanTests.java:38) ``` It's not entirely clear that we are correctly using the `DELEGATING` type here, perhaps the `PROPERTIES` type would be a better fit, however neither necessarily document support for a no-arg constructor. In general we prefer `DELEGATING` when possible to avoid ambiguity with potential property sources -- we want the ability to fail deserialization in this case when any properties are included in the incoming object. In 2.17.2, this branch allowed the code to functiona as we desired: https://github.com/FasterXML/jackson-databind/blob/091d968751ef00150d22a788fe7f45b7cdcb337a/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java#L658-L662 Is there any chance we could allow the previous DELEGATING behavior to continue to handle the no-arg case? If we'd prefer to move away from `DELEGATING` for that case, is there any chance we could emit a deprecation warning for some time? I've included a potential patch which recovers the previous behavior.
Describe your Issue
We need to rewrite the Bean Property introspection (see #3719 for background); and while this is ambitious undertaking, I think it should be done in Jackson 2.x timeframe, not 3.x. That way code remains potentially mergeable from 2.x to 3.x.
The main drivers for rewrite are to solve problems that are difficult if not impossible to solve with the current mechanism:
This issue is an umbrella ticket as refactoring will likely be spread across multiple PRs; they can all refer to this issue,
The text was updated successfully, but these errors were encountered: