apache/dubbo

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

Open

#16,197 opened on Apr 9, 2026

View on GitHub
 (1 comment) (0 reactions) (0 assignees)Java (26,453 forks)batch import
help wanted

Repository metrics

Stars
 (41,524 stars)
PR merge metrics
 (Avg merge 8d 14h) (28 merged PRs in 30d)

Description

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

Contributor guide