Skip to content

[Bug] List<Byte>, List<Short>, Map<String, Byte> deserialized as List<Integer>, Map<String, Integer> on provider side #16197

@uuuyuqi

Description

@uuuyuqi

Environment

  • Dubbo version: 3.2.x / 3.3.x (all versions affected)
  • Protocol: dubbo (hessian2) and triple (hessian2)
  • JDK: 17

Steps to reproduce

  1. Define an RPC interface with List<Byte> or Map<String, Byte> parameters:
public interface GreetingService {
    String processByteCollection(List<Byte> byteList, Map<String, Byte> byteMap);
}
  1. Consumer sends List<Byte> with values like (byte) 1, (byte) 2, (byte) 127
  2. Provider receives the parameters and checks element types

Expected behavior

Provider receives List<Byte> with elements of type java.lang.Byte.

Actual behavior

Provider receives List<Integer> — all Byte elements are deserialized as Integer. This causes ClassCastException when the provider code tries to use the elements as Byte.

Same issue affects List<Short>, List<Float>, Map<K, Byte>, Map<K, Short>, etc. — any collection/map with narrow number type arguments.

Root cause

Dubbo passes only the erased Class (e.g., List.class) to the serialization framework during request deserialization, discarding the generic Type (e.g., List<Byte>). The serialization framework (hessian2) has no way to know the element type should be Byte, so it defaults to Integer for small numbers.

Specifically:

  • ReflectionMethodDescriptor stores method.getParameterTypes() (raw Class[]) but not method.getGenericParameterTypes() (which includes ParameterizedType).
  • DecodeableRpcInvocation.drawArgs() only calls in.readObject(Class), never in.readObject(Class, Type).
  • ReflectionPackableMethod.WrapRequestUnpack similarly only passes Class<?>[] to MultipleSerialization.deserialize().
  • Hessian2ObjectInput.readObject(Class, Type) ignores the Type parameter entirely.

Tested & verified

  • Reproduced with Dubbo 3.3.6 (official release) on both dubbo and triple protocol
  • Fix verified with both dubbo and triple protocol via E2E testing
  • Verified with Arthas that the new code paths are executed at runtime

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedEverything needs help from contributors

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions