-
Notifications
You must be signed in to change notification settings - Fork 546
Closed
Labels
Milestone
Description
问题描述
使用 FastJSON2 的 JSONB 格式序列化和反序列化 AtomicLong 对象时,在反序列化阶段抛出 JSONException: readInt64Value not support TYPED_ANY -110 异常。该问题在启用 WriteClassName 特性时必现。
环境信息
- OS信息:Windows 10 / CentOS 7+
- JDK信息:OpenJDK 17.0.2 / OpenJDK 11.0.16
- 版本信息:Fastjson2 2.0.52 - 2.0.58 (多个版本测试均存在此问题)
- Dubbo版本:3.2.5 (在 Dubbo RPC 调用中发现此问题)
重现步骤
- 创建一个
AtomicLong对象 - 使用 JSONB 格式序列化,启用
WriteClassName特性 - 尝试反序列化为
AtomicLong对象 - 出现
readInt64Value not support TYPED_ANY -110错误
import com.alibaba.fastjson2.JSONB;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
import java.util.concurrent.atomic.AtomicLong;
public class FastJson2AtomicLongTest {
public static void main(String[] args) {
AtomicLong atomicLong = new AtomicLong(12345L);
// 序列化 - 成功
byte[] bytes = JSONB.toBytes(atomicLong,
JSONWriter.Feature.WriteClassName, // 问题的关键特性
JSONWriter.Feature.ReferenceDetection,
JSONWriter.Feature.WriteNulls,
JSONWriter.Feature.NotWriteDefaultValue,
JSONWriter.Feature.NotWriteHashMapArrayListClassName,
JSONWriter.Feature.WriteNameAsSymbol);
System.out.println("序列化成功,字节长度: " + bytes.length);
// 反序列化 - 失败
AtomicLong result = JSONB.parseObject(bytes, AtomicLong.class,
JSONReader.Feature.UseDefaultConstructorAsPossible,
JSONReader.Feature.ErrorOnNoneSerializable,
JSONReader.Feature.IgnoreAutoTypeNotMatch,
JSONReader.Feature.UseNativeObject);
System.out.println("反序列化结果: " + result.get());
}
}期待的正确结果
- 序列化和反序列化都应该成功完成
AtomicLong对象应该能够正确地被序列化为 JSONB 格式,并能够从 JSONB 格式正确反序列化- 反序列化后的
AtomicLong对象应该保持原始值12345L
相关日志输出
序列化成功,字节长度: 16
Exception in thread "main" com.alibaba.fastjson2.JSONException: readInt64Value not support TYPED_ANY -110, offset 1/16
at com.alibaba.fastjson2.JSONReaderJSONB.readInt64ValueError(JSONReaderJSONB.java:2625)
at com.alibaba.fastjson2.JSONReaderJSONB.readInt64Value0(JSONReaderJSONB.java:3540)
at com.alibaba.fastjson2.JSONReaderJSONB.readInt64Value(JSONReaderJSONB.java:3407)
at com.alibaba.fastjson2.reader.ObjectReaderImplFromLong.readJSONBObject(ObjectReaderImplFromLong.java:24)
at com.alibaba.fastjson2.JSONB.parseObject(JSONB.java:777)
at FastJson2AtomicLongTest.main(FastJson2AtomicLongTest.java:26)
实际应用场景中的错误
该问题在 Apache Dubbo 3.2.5 + FastJSON2 的生产环境中也会出现:
java.io.IOException: org.apache.dubbo.common.serialize.SerializationException: com.alibaba.fastjson2.JSONException: readInt64Value not support TYPED_ANY -110, offset 1/15
at org.apache.dubbo.common.serialize.DefaultSerializationExceptionWrapper.handleToIOException(DefaultSerializationExceptionWrapper.java:358)
at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.drawArgs(DecodeableRpcInvocation.java:267)
...
附加信息
临时解决方案:
- 去掉
WriteClassName特性(但会失去类型信息)
问题分析:
- 错误发生在
ObjectReaderImplFromLong.readJSONBObject()方法中 TYPED_ANY -110是 JSONB 格式中的特殊类型标记- 问题似乎与
WriteClassName特性写入的类型信息和AtomicLong的内部结构处理有关
影响范围:
- 所有使用 FastJSON2 JSONB 格式序列化
AtomicLong的场景 - 特别影响 Dubbo 等 RPC 框架的使用
- 同样可能影响
AtomicInteger等其他原子类型
希望能够修复此问题,使 FastJSON2 能够正确处理原子类型的序列化和反序列化。谢谢!