最近遇到个Kryo反序列化的错误com.esotericsoftware.kryo.KryoException: Encountered unregistered class ID: xxx,最后发现是 Kryo不同版本导致的,而且只在有 Map时才出现兼容性问题,觉得非常有意思,希望可以帮到有需要的人。

问题复现

Kryo稍微封装下

public class KryoSerializer {/*** 解决线程安全问题*/private static final ThreadLocal<Kryo> kryoPool = ThreadLocal.withInitial(() -> {Kryo temp = new Kryo();temp.setReferences(false);return temp;});public static byte[] serialize(Object object) {ByteArrayOutputStream bos = new ByteArrayOutputStream(4096);Output output = new Output(bos, 1024);kryoPool.get().writeClassAndObject(output, object);output.flush();return bos.toByteArray();}public static Object deserialize(byte[] bytes) {Input input = new Input(bytes);return kryoPool.get().readClassAndObject(input);}public static void setClassLoader(ClassLoader classLoader) {kryoPool.get().setClassLoader(classLoader);}
}

准备一个带Map的简单类

import java.util.HashMap;
import java.util.Map;public class Param {public String name;public Map<String, Object> conf = new HashMap<>(4);public Param() {}public Param(String name) {this.name = name;}@Overridepublic String toString() {return "Param{" +"name='" + name + '\'' +", conf=" + conf +'}';}
}

测试的序列化和反序列化方法

我们首先将使用的Kryo版本打印出来。

private static void deserialize() {System.out.println(Kryo.class.getProtectionDomain().getCodeSource().getLocation().getPath());String s = "AQBjb20uamltby5QYXJh7QEBamF2YS51dGlsLkhhc2hNYfABA2517QLIAWppbe8=";final Object obj = KryoSerializer.deserialize(EncodeUtil.base64DecodeBytes(s));System.out.println(obj);
}private static void serialize() {System.out.println(Kryo.class.getProtectionDomain().getCodeSource().getLocation().getPath());final Param p = new Param("jimo");p.conf.put("num", 100);final byte[] bytes = KryoSerializer.serialize(p);System.out.println(EncodeUtil.base64EncodeBytes(bytes));
}

如何控制Kryo版本呢?

很简单,手动注释不同的版本。

    <dependencies><!--<dependency><groupId>com.esotericsoftware</groupId><artifactId>kryo</artifactId><version>4.0.2</version></dependency>--><dependency><groupId>com.esotericsoftware</groupId><artifactId>kryo</artifactId><version>3.0.3</version></dependency></dependencies>

接下来就可以开始实验了。

Kryo3序列化–Kryo4反序列化

首先将pom里的Kryo版本设为3.0.3,我们测试当使用低版本序列化,高版本反序列化时,会不会出问题。

序列化结果如下:

/D:/maven_repository/com/esotericsoftware/kryo-shaded/3.0.3/kryo-shaded-3.0.3.jar
AQBjb20uamltby5QYXJh7QEBamF2YS51dGlsLkhhc2hNYfABbnXtAsgBamlt7w==

接着将pom里的Kryo版本设为 4.0.2, 通过Kryo4反序列化,得到如下报错:

/D:/maven_repository/com/esotericsoftware/kryo/4.0.2/kryo-4.0.2.jar
Exception in thread "main" com.esotericsoftware.kryo.KryoException: Encountered unregistered class ID: 108
Serialization trace:
conf (com.jimo.Param)at com.esotericsoftware.kryo.util.DefaultClassResolver.readClass(DefaultClassResolver.java:137)at com.esotericsoftware.kryo.Kryo.readClass(Kryo.java:693)at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:804)at com.esotericsoftware.kryo.serializers.MapSerializer.read(MapSerializer.java:153)at com.esotericsoftware.kryo.serializers.MapSerializer.read(MapSerializer.java:39)at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:734)at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:125)at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:543)at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:816)at com.jimo.KryoSerializer.deserialize(KryoSerializer.java:30)at com.jimo.Main.deserialize(Main.java:18)at com.jimo.Main.main(Main.java:8)

可以看出,这是版本问题导致的。Kryo能否向下兼容呢?

Kryo4序列化–Kryo3反序列化

将pom里的Kryo版本设为 4.0.2,然后执行序列化结果如下:

/D:/maven_repository/com/esotericsoftware/kryo/4.0.2/kryo-4.0.2.jar
AQBjb20uamltby5QYXJh7QEBamF2YS51dGlsLkhhc2hNYfABA2517QLIAWppbe8=

再将pom里的Kryo版本设为3.0.3, Kryo3反序列化结果如下:

/D:/maven_repository/com/esotericsoftware/kryo-shaded/3.0.3/kryo-shaded-3.0.3.jar
Param{name='jimo', conf={num=100}}

咋一看能反序列化,好像是向下兼容的。
但是,仔细一看,发现map里面的key多了个字符,这是个什么字符呢?

通过断点可以看到,这是 \u0003, 含义是 ETX,也就是退出,平常用的 Ctrl+C.

总结

在笔者场景下,会通过 Kryo序列化得到的byte数组再经过Base64转换为字符串,传输到Spark-YARN环境再反序列化,结果出现了反序列化报错。后面发现,这是由于 Kryo版本不一致导致的。

对于Kryo的兼容性问题,建议都保持同一个版本,跨版本的兼容很难保证,特别是在有 Map的情况下。

com.esotericsoftware.kryo.KryoException: Encountered unregistered class ID相关推荐

  1. spark:报错com.esotericsoftware.kryo.KryoException: Buffer underflow.

    场景 spark-sql跑一个较大的任务,数据落盘时报错: com.esotericsoftware.kryo.KryoException: Buffer underflow. Caused by: ...

  2. 【Dubbo】序列化异常—— com.esotericsoftware.kryo.KryoException: Buffer underflow

    Dubbo服务通常依赖一个jar包来表示服务签名,其中包含了服务的接口定义. 服务的提供者(服务端)需实现这些接口: 服务的调用者(客户端)可以通过这些接口调用服务. 问题 此文提到的异常 " ...

  3. com.esotericsoftware.kryo.KryoException: Buffer underflow. 解决

    用kryo进行序列化和反序列化的时候,序列化的过程很顺利,反序列化的过程中遇到报错KryoException: Buffer underflow. 代码如下: //其中path是将序列化对象保存的路径 ...

  4. EsotericSoftware Kryo —— 官方(1)

    kryo是什么 kryo 是一个针对Java的快速,高效的二进制对象图形序列化框架. kryo目标 kryo的目标是高速.占用空间小.并且有简单好用的api 随时为Java对象提供持久化的能力,包括持 ...

  5. 诡异的encountered unrecognized patch id:FMJJ,看不见的因果

    单位的几台外网weblogic应用服务器,由于未修复WSAT组件RCE漏洞,导致受到攻击. 找了oracle原厂过来升级weblogic,一些不重要的系统便留给了我练练手. 结果第一台服务器就遇到问题 ...

  6. livy提交任务报错com.cloudera.livy.shaded.kryo.kryo.KryoException: Unable to find class: GATest.ConJob

    今天在测试的时候,出现这个错误,找了好久网上找不到,最近尝试多次终于成功了. 问题就在于:Unable to find class 你要把你已经uploadJar的jar包中包含的类,引入工程. 我用 ...

  7. dubbo kryo序列化_为什么如此高效?解密kryo各个数据类型的序列化编码机制,强...

    用过dubbo的开发人员,在替换序列化时都会根据"经验"来选kryo为序列化框架,其原因是序列化协议非常高效,超过java原生序列化协议,hessian2协议,那kryo为什么高效 ...

  8. avro和java原生序列化的区别,java原生序列化和Kryo序列化性能比较

    简介 最近几年,各种新的高效序列化方式层出不穷,不断刷新序列化性能的上限,最典型的包括: 专门针对Java语言的:Kryo,FST等等 跨语言的:Protostuff,ProtoBuf,Thrift, ...

  9. krait和kryo_java原生序列化和Kryo序列化性能比较

    简介 最近几年,各种新的高效序列化方式层出不穷,不断刷新序列化性能的上限,最典型的包括: 专门针对Java语言的:Kryo,FST等等 跨语言的:Protostuff,ProtoBuf,Thrift, ...

  10. krait和kryo_java原生序列化和Kryo序列化性能实例对比分析

    简介 最近几年,各种新的高效序列化方式层出不穷,不断刷新序列化性能的上限,最典型的包括: 专门针对java语言的:Kryo,FST等等 跨语言的:Protostuff,ProtoBuf,Thrift, ...

最新文章

  1. FPGA基础知识极简教程(6)UART通信与移位寄存器的应用
  2. java吃豆游戏_利用java编写的精灵吃豆的游戏
  3. 性能测试(06)-逻辑控制器
  4. JSON与XML优缺点对比分析
  5. Maven学习五之Nexus中各repository介绍
  6. android mapstring, string遍历,MapString, String 遍历的四种方法
  7. spring相关技术实现的核心原理
  8. html按钮调用php函数,如何在html按钮上执行php函数点击
  9. 微信点餐小程序设计与实现(一)
  10. 数字证书认证(CA)中心
  11. 找素数模板:马氏筛法【复杂度nlgnlgn】
  12. TPS929120的CRC校验的三种实现方法
  13. 计算机office二级考试手册,二级office助考手册app
  14. (转)计算机领域的顶级会议和期刊
  15. Lua游戏中常用到的一些动作
  16. Oracle - LOB(大对象数据类型)
  17. 云师大计算机调剂,云南师范大学调剂公告
  18. 电脑计算机管理声音,教你如何解决电脑声音不正常
  19. 软件架构场景之—— 数据同步:如何解决微服务之间的数据依赖问题?
  20. tensorflow学习笔记(开篇综述)

热门文章

  1. Contrastive Loss
  2. tar的--exclude选项中PATTERN详解
  3. 售前技能——自我定位
  4. 除硬件外 计算机系统不可缺少的,计算机应用基础选择精选100题.doc
  5. 蓝桥杯题目---蓝桥骑士(寻找逐渐递增的子序列 最多个数)
  6. linux wipe命令,如何使用wipefs命令擦除磁盘上的签名
  7. 人体一机竞技格斗机器人_在格斗机器人比赛中,如何判断输赢?
  8. Qt Moc 文件解析
  9. matlab plot bo,Matlab的plot~各种颜色和线形
  10. CSS div斜线倾斜45度