Java序列化_unknown object tag -126

项目场景:

第一次进入获取员工信息的方法时,会先通过序列化数据库的对应员工信息并保存到 Redis 中。
第二次进入获取员工信息的方法时,直接取出 Redis 里序列化后员工信息,进行反序列化后返回。


问题描述

这里是第一次保存成功后,第二次反序列化的时候,一直提示反序列化某个字符异常。

这里我写了一个对应的简单测试

功能:

  1. 获取对应的序列化工具包
  2. 通过工具包序列化 User 对象为字节
  3. 通过工具包把字节转换成 User 对象

其中 FstSerializer 是一个对应的序列化类

public static void main(String[] args) throws Exception {
		FstSerializer instance = FstSerializer.getInstance();
		// 由于业务数据需要保密,这里可以理解为一个user对象的Json串
		String jsonS = "{\"userId\":1,\"userNamel\":zs\",\"amount\":2.00......\"\"}";
        User user= JsonUtil.str2Object(jsonS, User.class);
		byte[] serialize = instance.serialize(user);
		User deserialize = instance.deserialize(serialize, User.class);
		System.out.println(deserialize.getUserId());
}		

运行时候会抛出解析某个字节异常 (细心的话可以发现有一个BigDecimal 的报错)

Java序列化_unknown object tag -126_第1张图片

原因分析:

  1. 一开始的第一想法是从 unknown object tag -126 入手,但是在网上找了好久没有对应的解决方案。
  2. 接着考虑到序列化的工具包是我们公司自己封装的,会不会是工具包解析有异常呢。
    (自己在那 debug 了半天,没发现什么问题)
  3. 接着又想到让同事跑一下相同的代码,看一下有什么问题吗。
    (诡异的事情发生了,他的电脑是可以正常反序列出来的)
  4. 这时候,我已经有点郁闷了。别人不出问题,就我有问题。
    (那环境或者对应的版本号有问题吗)

看了许久,对了项目仓库版本号啥的,一切都是一致的。
最后又反回去看了一下报错(重要的遗漏点 ===> 一开始以为Jdk 的类能有什么好看的呢): at java.math.BigDecimal.readObject(BigDecimal.java:3798)
Java序列化_unknown object tag -126_第2张图片
最后,大哥给了我一个大胆的猜想:会不会是 JDK 版本有 bug 呢
我对了一下我们两个机器的 jdk 版本号。
我的机器: 1.8.0_351
同事的机器: 1.8.0_301

然后我们对比了两个人 BigDecimal 类中的 readObject 方法
1.8.0_351 (报错的那一行)

Java序列化_unknown object tag -126_第3张图片
1.8.0_301 (正常运行版本中的方法)

Java序列化_unknown object tag -126_第4张图片

解决方案:

底层代码我也没有去深究了,我把 jdk 的版本降为 1.8.0_301。重新运行后,它可以正常反序列化,并拿到对应的 userId。
Java序列化_unknown object tag -126_第5张图片
升级后,可能是对 BigDecimal 读取属性值没有做兼容。导致反序列化的时候,出了异常;只能说这种情况还是十分低的。如果遇到同样的问题,希望对你有所帮助。

你可能感兴趣的:(项目Tips,java,redis,Java,序列化)