You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a property uses @JsonSerialize(keyUsing = ...), a Map contained in that Map's values currently reads the same property annotation again. This can pass an inner String key to a serializer for an outer custom key type and throw ClassCastException, or silently rewrite inner keys when the key types happen to match.
This change gives Map contents a private BeanProperty view after the enclosing Map has consumed the property's key serializer. Nested Map serializers recognize that view and skip reapplying the property-level key override. The view delegates the other property metadata so that sorting, inclusion rules, and contextual value serializers retain their configuration. Nested maps still use their own class-level or module-provided key serializers.
The content-converter recursion guard compares properties by identity. A small protected helper in StdSerializer lets MapSerializer check the original property before switching to the content view, preserving converters on enclosing Optional, List, and AtomicReference properties that produce a Map.
The scope is property-level keyUsing propagation into Map values; this does not introduce a general annotation-scoping API for all container serializers. The private property view and its interaction with contextual serializers are the main design points for review.
Validation:
26 focused cases cover the original reproducer, same-type keys, static and dynamic typing, nested containers, converters, property metadata, class/module overrides, and cache warm-up order.
The same cases on the unchanged upstream baseline yield 10 passes, 6 assertion failures, and 10 errors. The enclosing-container converter cases pass on that baseline and with this change.
clean verify passes on JDK 17, 21, and 25: 7,468 tests on each, with 0 failures, 0 errors, and 1 skipped test.
animal-sniffer:check passes on JDK 17 against the Android API 34 signature.
For the local full builds, Mockito was loaded explicitly with -javaagent because dynamic attachment is unavailable on this host; the repository's POM and CI configuration are unchanged.
🟡 Medium risk · Changes scope of property-level key serializers across nested Map values.
Fixes property key serializer leaking into nested maps by giving Map contents a private BeanProperty view after the enclosing Map consumes the property's key serializer, preventing ClassCastException and silent key rewrites. Nested maps recognize this view and skip reapplying property-level key overrides while retaining sorting, inclusion rules, and contextual value serializers. Comprehensive test coverage (26 focused cases) and full test suite validation (7,468 tests) confirm the fix works correctly. No issues found.
Auto-apply is off → Gitar will not commit updates to this branch. Display: compact → Counting what did not apply, without listing it.
Comment with these commands to change the behavior for this request:
Auto-apply
Compact
gitar auto-apply:on
gitar display:verbose
Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source
This branch has not been deployed
No deployments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2050.
When a property uses
@JsonSerialize(keyUsing = ...), a Map contained in that Map's values currently reads the same property annotation again. This can pass an inner String key to a serializer for an outer custom key type and throwClassCastException, or silently rewrite inner keys when the key types happen to match.This change gives Map contents a private
BeanPropertyview after the enclosing Map has consumed the property's key serializer. Nested Map serializers recognize that view and skip reapplying the property-level key override. The view delegates the other property metadata so that sorting, inclusion rules, and contextual value serializers retain their configuration. Nested maps still use their own class-level or module-provided key serializers.The content-converter recursion guard compares properties by identity. A small protected helper in
StdSerializerletsMapSerializercheck the original property before switching to the content view, preserving converters on enclosingOptional,List, andAtomicReferenceproperties that produce a Map.The scope is property-level
keyUsingpropagation into Map values; this does not introduce a general annotation-scoping API for all container serializers. The private property view and its interaction with contextual serializers are the main design points for review.Validation:
clean verifypasses on JDK 17, 21, and 25: 7,468 tests on each, with 0 failures, 0 errors, and 1 skipped test.animal-sniffer:checkpasses on JDK 17 against the Android API 34 signature.For the local full builds, Mockito was loaded explicitly with
-javaagentbecause dynamic attachment is unavailable on this host; the repository's POM and CI configuration are unchanged.