fix: preserve nested generic element types during hessian2 deserialization (#16440) [3.3] - #16441
Open
waterWang wants to merge 1 commit into
Open
fix: preserve nested generic element types during hessian2 deserialization (#16440) [3.3]#16441waterWang wants to merge 1 commit into
waterWang wants to merge 1 commit into
Conversation
waterWang
force-pushed
the
fix/nested-generic-16440
branch
from
August 27, 2026 16:40
0e3b230 to
268542e
Compare
5 tasks
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## 3.3 #16441 +/- ##
============================================
- Coverage 60.90% 58.92% -1.98%
+ Complexity 11765 15 -11750
============================================
Files 1953 1953
Lines 89271 89335 +64
Branches 13473 13497 +24
============================================
- Hits 54367 52641 -1726
- Misses 29321 30986 +1665
- Partials 5583 5708 +125
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…hessian2 deserialization (apache#16440) hessian2 encodes Byte/Short/Integer all as int and Float/Double as double on the wire, so the narrow element types of generic collections can only be restored from the declared generic type. On the provider side the request arguments were decoded with only the erased Class, so nested generics such as Map<String, List<Byte>> or List<List<Byte>> lost the inner element type and deserialized as Integer/Double, causing ClassCastException on typed access. This change: - exposes the generic parameter types on MethodDescriptor/ ReflectionMethodDescriptor; - passes the generic parameter type through DecodeableRpcInvocation when decoding request arguments; - makes Hessian2ObjectInput.readObject(Class, Type) recursively narrow numeric elements (Byte/Short/Float/Character) inside nested generic collections to match the declared generic type. Signed-off-by: waterWang <waterWang@users.noreply.github.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What is the purpose of the change?
Fixes #16440 — hessian2 deserialization loses Byte/Short/Float element types in nested generic collections (
List<List<Byte>>,Map<String, List<Byte>>), widening them toInteger/Doubleon the provider side and causingClassCastExceptionon typed access.Root cause
hessian2 encodes
Byte/Short/Integerall asintandFloat/Doubleasdoubleon the wire, so narrow element types can only be restored from the declared generic type. Two problems combined:DecodeableRpcInvocation.drawArgs) with only the erasedClass, discarding the generic parameter types entirely.Typewas available,Hessian2ObjectInput.readObject(Class, Type)ignored it, and hessian-lite'sexpectedTypesmechanism only handles a single level — nested element types (e.g. theByteinsideMap<String, List<Byte>>) are still widened.How this is fixed
MethodDescriptor/ReflectionMethodDescriptor: exposegetGenericParameterTypes().DecodeableRpcInvocation: capture the generic parameter types when looking up the method and pass them toObjectInput.readObject(Class, Type).Hessian2ObjectInput.readObject(Class, Type): when the declared type is a parameterized collection/map containing narrow wrapper types (Byte/Short/Float/Character), read the object with the erased type and recursively narrow numeric elements to the declared generic element types. Types without narrowable elements (e.g.List<String>) keep the original native path.Verification
testReadObjectWithNestedGenericTypeinHessian2SerializationTestcoveringMap<String, List<Byte>>,List<List<Byte>>,Map<String, List<Float>>, simpleList<Byte>and an untouchedList<String>.mvn -pl dubbo-serialization/dubbo-serialization-hessian2 -am test— all 809 tests pass (incl. 798TypeMatchTest).dubbo-commonanddubbo-rpc/dubbo-rpc-dubbocompile.Checklist