com.esotericsoftware.kryo.KryoException: Encountered unregistered class ID
最近遇到个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相关推荐
- spark:报错com.esotericsoftware.kryo.KryoException: Buffer underflow.
场景 spark-sql跑一个较大的任务,数据落盘时报错: com.esotericsoftware.kryo.KryoException: Buffer underflow. Caused by: ...
- 【Dubbo】序列化异常—— com.esotericsoftware.kryo.KryoException: Buffer underflow
Dubbo服务通常依赖一个jar包来表示服务签名,其中包含了服务的接口定义. 服务的提供者(服务端)需实现这些接口: 服务的调用者(客户端)可以通过这些接口调用服务. 问题 此文提到的异常 " ...
- com.esotericsoftware.kryo.KryoException: Buffer underflow. 解决
用kryo进行序列化和反序列化的时候,序列化的过程很顺利,反序列化的过程中遇到报错KryoException: Buffer underflow. 代码如下: //其中path是将序列化对象保存的路径 ...
- EsotericSoftware Kryo —— 官方(1)
kryo是什么 kryo 是一个针对Java的快速,高效的二进制对象图形序列化框架. kryo目标 kryo的目标是高速.占用空间小.并且有简单好用的api 随时为Java对象提供持久化的能力,包括持 ...
- 诡异的encountered unrecognized patch id:FMJJ,看不见的因果
单位的几台外网weblogic应用服务器,由于未修复WSAT组件RCE漏洞,导致受到攻击. 找了oracle原厂过来升级weblogic,一些不重要的系统便留给了我练练手. 结果第一台服务器就遇到问题 ...
- livy提交任务报错com.cloudera.livy.shaded.kryo.kryo.KryoException: Unable to find class: GATest.ConJob
今天在测试的时候,出现这个错误,找了好久网上找不到,最近尝试多次终于成功了. 问题就在于:Unable to find class 你要把你已经uploadJar的jar包中包含的类,引入工程. 我用 ...
- dubbo kryo序列化_为什么如此高效?解密kryo各个数据类型的序列化编码机制,强...
用过dubbo的开发人员,在替换序列化时都会根据"经验"来选kryo为序列化框架,其原因是序列化协议非常高效,超过java原生序列化协议,hessian2协议,那kryo为什么高效 ...
- avro和java原生序列化的区别,java原生序列化和Kryo序列化性能比较
简介 最近几年,各种新的高效序列化方式层出不穷,不断刷新序列化性能的上限,最典型的包括: 专门针对Java语言的:Kryo,FST等等 跨语言的:Protostuff,ProtoBuf,Thrift, ...
- krait和kryo_java原生序列化和Kryo序列化性能比较
简介 最近几年,各种新的高效序列化方式层出不穷,不断刷新序列化性能的上限,最典型的包括: 专门针对Java语言的:Kryo,FST等等 跨语言的:Protostuff,ProtoBuf,Thrift, ...
- krait和kryo_java原生序列化和Kryo序列化性能实例对比分析
简介 最近几年,各种新的高效序列化方式层出不穷,不断刷新序列化性能的上限,最典型的包括: 专门针对java语言的:Kryo,FST等等 跨语言的:Protostuff,ProtoBuf,Thrift, ...
最新文章
- FPGA基础知识极简教程(6)UART通信与移位寄存器的应用
- java吃豆游戏_利用java编写的精灵吃豆的游戏
- 性能测试(06)-逻辑控制器
- JSON与XML优缺点对比分析
- Maven学习五之Nexus中各repository介绍
- android mapstring, string遍历,MapString, String 遍历的四种方法
- spring相关技术实现的核心原理
- html按钮调用php函数,如何在html按钮上执行php函数点击
- 微信点餐小程序设计与实现(一)
- 数字证书认证(CA)中心
- 找素数模板:马氏筛法【复杂度nlgnlgn】
- TPS929120的CRC校验的三种实现方法
- 计算机office二级考试手册,二级office助考手册app
- (转)计算机领域的顶级会议和期刊
- Lua游戏中常用到的一些动作
- Oracle - LOB(大对象数据类型)
- 云师大计算机调剂,云南师范大学调剂公告
- 电脑计算机管理声音,教你如何解决电脑声音不正常
- 软件架构场景之—— 数据同步:如何解决微服务之间的数据依赖问题?
- tensorflow学习笔记(开篇综述)