ORMLite中HashSet序列化大小字节错误的原因排查
HashSet序列化字节大小错误的已知原因排查
我在应用中通过ORMLite定义并存储HashSet<String>类型字段,代码如下:
@DatabaseField(dataType = DataType.SERIALIZABLE) private HashSet<String> allUsers;
部分设备偶尔出现该字段序列化时大小字节错误的问题,导致无法反序列化。示例错误信息(含模拟数据):
java.sql.SQLException: Could not read serialized object from byte array: [-84, -19, 0, 5, 115, 114, 0, 17, 106, 97, 118, 97, 46, 117, 116, 105, 108, 46, 72, 97, 115, 104, 83, 101, 116, -70, 68, -123, -107, -106, -72, -73, 52, 3, 0, 0, 120, 112, 119, 12, 0, 0, 0, 16, 63, 64, 0, 0, 0, 0, 0, /* this is the problem byte */ 3, 116, 0, 4, 115, 111, 109, 101, 116, 0, 4, 100, 97, 116, 97, 120]
若将大小字节修正为正确值(如下方数组中的2),即可成功反序列化为包含两个字符串的HashSet:
[-84, -19, 0, 5, 115, 114, 0, 17, 106, 97, 118, 97, 46, 117, 116, 105, 108, 46, 72, 97, 115, 104, 83, 101, 116, -70, 68, -123, -107, -106, -72, -73, 52, 3, 0, 0, 120, 112, 119, 12, 0, 0, 0, 16, 63, 64, 0, 0, 0, 0, 0, /* correct size is 2 */ 2, 116, 0, 4, 115, 111, 109, 101, 116, 0, 4, 100, 97, 116, 97, 120]
我尝试通过序列化、反序列化、增删元素后再序列化的方式复现问题,但未成功。想了解Java中HashSet出现此类序列化大小错误的已知原因。
可能的已知原因
- 并发修改引发的不一致:HashSet是非线程安全容器,若序列化过程中有其他线程对其进行增删操作,会导致序列化时写入的元素数量(size字段)和实际序列化的元素数量不匹配。比如序列化开始时记录size为3,但过程中元素被删除一个,最终只序列化了2个元素,就会出现字节数组中size值与实际元素数量不符的情况。
- 特定JVM/ART版本的序列化Bug:部分老旧的Android Runtime(ART)或JVM版本中,HashSet的序列化实现可能存在边缘场景Bug,比如处理扩容状态、空元素时的逻辑异常,导致size字段写入错误。
- 数据库IO过程中的字节损坏:数据库存储或读取字节数组时,若出现IO异常、存储介质故障或数据传输错误,可能会篡改记录size的字节,导致反序列化时大小不匹配。
- ORMLite序列化逻辑的潜在问题:ORMLite对SERIALIZABLE类型的处理,可能在极端场景下存在疏漏,比如未正确锁定待序列化对象,或者对序列化后的字节数组进行截断、拼接时出错,导致size字段异常。
内容的提问来源于stack exchange,提问作者user23368169
相关产品推荐
相关产品推荐

