问题描述
FastJSON2版本从2.0.49升级到2.0.59后,在Dubbo框架中反序列化包含Collections.EMPTY_LIST的对象时抛出异常。错误信息显示IllegalAccessException: Class com.alibaba.fastjson2.reader.ObjectReaderImplListStr can not access a member of class java.util.Collections$EmptyList with modifiers "private"。
环境信息
请填写以下信息:
- OS信息:Linux/Windows
- JDK信息:JDK 21
- 版本信息:Fastjson2 2.0.59(从2.0.49升级后出现问题)
- 框架信息:Apache Dubbo
重现步骤
如何操作可以重现该问题:
- 创建一个包含
Collections.EMPTY_LIST字段的Java对象
- 在Dubbo服务中返回该对象
- 客户端调用服务时,FastJSON2尝试反序列化该对象
- 出现
IllegalAccessException错误,无法访问Collections$EmptyList的私有成员
import java.util.Collections;
import java.util.List;
// 示例返回对象
public class ResponseObject {
private String name;
private List<String> items = Collections.EMPTY_LIST; // 问题所在
// getter/setter方法
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public List<String> getItems() { return items; }
public void setItems(List<String> items) { this.items = items; }
}
// Dubbo服务接口
public interface TestService {
ResponseObject getResponse();
}
// Dubbo服务实现
@Service
public class TestServiceImpl implements TestService {
@Override
public ResponseObject getResponse() {
ResponseObject response = new ResponseObject();
response.setName("test");
// items字段默认为Collections.EMPTY_LIST
return response; // 这里会在客户端反序列化时出错
}
}
期待的正确结果
对您期望发生的结果进行清晰简洁的描述。
期望FastJSON2能够正确处理Collections.EMPTY_LIST的序列化和反序列化,就像在2.0.49版本中一样正常工作,不应该因为访问权限问题而抛出IllegalAccessException。
相关日志输出
请复制并粘贴任何相关的日志输出。
java.io.IOException: org.apache.dubbo.common.serialize.SerializationException: com.alibaba.fastjson2.JSONException: create instance error class java.util.Collections$EmptyList, offset 213
at org.apache.dubbo.common.serialize.DefaultSerializationExceptionWrapper.handleToIOException(DefaultSerializationExceptionWrapper.java:358)
at org.apache.dubbo.common.serialize.DefaultSerializationExceptionWrapper.access$000(DefaultSerializationExceptionWrapper.java:28)
at org.apache.dubbo.common.serialize.DefaultSerializationExceptionWrapper$ProxyObjectInput.readObject(DefaultSerializationExceptionWrapper.java:177)
at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcResult.handleValue(DecodeableRpcResult.java:192)
at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcResult.decode(DecodeableRpcResult.java:125)
... (省略部分堆栈信息)
Caused by: org.apache.dubbo.common.serialize.SerializationException: com.alibaba.fastjson2.JSONException: create instance error class java.util.Collections$EmptyList, offset 213
... 222 more
Caused by: com.alibaba.fastjson2.JSONException: create instance error class java.util.Collections$EmptyList, offset 213
at com.alibaba.fastjson2.reader.ObjectReaderImplListStr.readJSONBObject(ObjectReaderImplListStr.java:153)
at com.alibaba.fastjson2.reader.FieldReaderObject.readFieldValueJSONB(FieldReaderObject.java:206)
at com.alibaba.fastjson2.reader.ObjectReaderAdapter.readFieldValue(ObjectReaderAdapter.java:507)
at com.alibaba.fastjson2.JSONB.parseObject(JSONB.java:879)
at org.apache.dubbo.common.serialize.fastjson2.FastJson2ObjectInput.readObject(FastJson2ObjectInput.java:151)
... 219 more
Caused by: java.lang.IllegalAccessException: Class com.alibaba.fastjson2.reader.ObjectReaderImplListStr can not access a member of class java.util.Collections$EmptyList with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.Class.newInstance(Class.java:436)
at com.alibaba.fastjson2.reader.ObjectReaderImplListStr.readJSONBObject(ObjectReaderImplListStr.java:151)
... 225 more
问题分析:
Collections.EMPTY_LIST是Collections$EmptyList的实例,该类的构造函数是私有的
- FastJSON2 2.0.59版本在反序列化时尝试通过反射调用
Collections$EmptyList的构造函数
- 由于访问权限限制,抛出
IllegalAccessException异常
- 该问题在FastJSON2 2.0.49版本中不存在,说明是版本升级引入的回归问题
影响范围:
- 所有使用
Collections.EMPTY_LIST、Collections.EMPTY_SET、Collections.EMPTY_MAP作为默认值的对象
- 在Dubbo等RPC框架中传输此类对象时会失败
- 影响生产环境的稳定性
临时解决方案:
- 将
Collections.EMPTY_LIST替换为new ArrayList<>()
- 或者使用
Collections.emptyList()方法
- 降级到FastJSON2 2.0.46版本
// 问题代码
private List<String> items = Collections.EMPTY_LIST;
// 临时解决方案1
private List<String> items = new ArrayList<>();
// 临时解决方案2
private List<String> items = Collections.emptyList();
建议的修复方案:
FastJSON2应该为Collections$EmptyList等JDK内置的不可变集合类提供特殊处理,而不是尝试通过反射创建实例。
问题描述
FastJSON2版本从2.0.49升级到2.0.59后,在Dubbo框架中反序列化包含
Collections.EMPTY_LIST的对象时抛出异常。错误信息显示IllegalAccessException: Class com.alibaba.fastjson2.reader.ObjectReaderImplListStr can not access a member of class java.util.Collections$EmptyList with modifiers "private"。环境信息
请填写以下信息:
重现步骤
如何操作可以重现该问题:
Collections.EMPTY_LIST字段的Java对象IllegalAccessException错误,无法访问Collections$EmptyList的私有成员期待的正确结果
对您期望发生的结果进行清晰简洁的描述。
期望FastJSON2能够正确处理
Collections.EMPTY_LIST的序列化和反序列化,就像在2.0.49版本中一样正常工作,不应该因为访问权限问题而抛出IllegalAccessException。相关日志输出
请复制并粘贴任何相关的日志输出。
问题分析:
Collections.EMPTY_LIST是Collections$EmptyList的实例,该类的构造函数是私有的Collections$EmptyList的构造函数IllegalAccessException异常影响范围:
Collections.EMPTY_LIST、Collections.EMPTY_SET、Collections.EMPTY_MAP作为默认值的对象临时解决方案:
Collections.EMPTY_LIST替换为new ArrayList<>()Collections.emptyList()方法建议的修复方案:
FastJSON2应该为
Collections$EmptyList等JDK内置的不可变集合类提供特殊处理,而不是尝试通过反射创建实例。