Kryo 3.0 反序列化的问题

发布于 2021-12-01 12:16:10 字数 2108 浏览 982 评论 19

之前 Kryo 2.x 版本时候就更多问题,今天发布了 3.0 版本,升级一下试着对一个字符串列表进行序列化和反序列化后还是出错,报错如下:
Exception in thread "main" java.lang.NullPointerException
	at java.util.Arrays$ArrayList.size(Arrays.java:3812)
	at java.util.AbstractList.add(AbstractList.java:108)
	at com.esotericsoftware.kryo.serializers.CollectionSerializer.read(CollectionSerializer.java:116)
	at com.esotericsoftware.kryo.serializers.CollectionSerializer.read(CollectionSerializer.java:22)
	at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:786)
	at net.oschina.j2cache.util.KryoSerializer.deserialize(KryoSerializer.java:51)
	at net.oschina.j2cache.util.SerializationUtils.deserialize(SerializationUtils.java:68)
	at net.oschina.j2cache.util.SerializationUtils.main(SerializationUtils.java:31)
代码其实超级简单:
private final static Kryo kryo = new Kryo();

public static void main(String[] args) throws IOException {
	
	List<String> obj = Arrays.asList("OSChina.NET","Team@OSC", "Git@OSC", "Sonar@OSC");
	byte[] bits = serialize(obj);
	for(byte b : bits){
		System.out.print(Byte.toString(b)+" ");
	}
	System.out.println();
	System.out.println(bits.length);
	System.out.println(deserialize(bits));
	
}

public static byte[] serialize(Object obj) throws IOException {
	Output output = null;
	try {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		output = new Output(baos);
		kryo.writeClassAndObject(output, obj);
		output.flush();
		return baos.toByteArray();
	}finally{
		if(output != null)
			output.close();
	}
}

public static Object deserialize(byte[] bits) throws IOException {
	if(bits == null || bits.length == 0)
		return null;
	Input ois = null;
	try {
		ByteArrayInputStream bais = new ByteArrayInputStream(bits);
		ois = new Input(bais);
		return kryo.readClassAndObject(ois);
	} finally {
		if(ois != null)
			ois.close();
	}
}

而之前的 2.x 版本提示错误信息的是 ArrayList 没有不带参数的构造函数。

好吧,我喜欢 FST 多于 Kryo

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(19

奈何桥上唱咆哮 2021-12-01 18:00:27

我用fst ,kyro很多bug

悸初 2021-12-01 18:00:25

我已经找到原因了,不过可惜架构师换了缓存框架,放弃了redis,使用了ehcache+tc,用了一段时间,感觉还是不如redis好。kyro序列化作者把transient属性直接设置为不参与序列化,并且这个值是写死在代码里的。shiro的原生session实现很多属性带有transient关键字,并且自己实现了readObect,writeObject方法,需要序列化器兼容JDK原生序列化。解决方法有2个,一个是重写shiro的session实现,另外一个是使用kyro是注册session类的序列化器为JDK原生(就跟没用差不多了,不过实测性能稍微提高了一点),或者换用fst。分布式环境下,session的信息保存使用ehcache+tc还是不如ehcache+redis,或者直接走redis

勿忘初心 2021-12-01 18:00:19

HttpSession序列化? 应该是不行吧, 你能把HttpServletRequest对象序列化吗?同理的, HttpSession包含连接状态,如何能序列化呢。。。

后知后觉 2021-12-01 18:00:18

晕得很, kryo 不能序列化 session 比如 变量类型是 serializable 的变量 ,kryo 无法序列化

英雄似剑 2021-12-01 18:00:18

回复
可以缓存

情场扛把子 2021-12-01 17:59:51

缓存的是settributes map,sessionId等信息,分布式运用

初见你 2021-12-01 17:59:37

回复
@xchm :

绝情姑娘 2021-12-01 17:58:44

架构师想用redis来缓存HttpSession,指定使用kryo作为序列化工具,我在实现的时候发现Kryo没办法反序列化HttpSession。不知道有没有其他的序列化工具好用点,另外使用EHcache+tc来缓存session和用redis来缓存session哪个好点
@红薯

成熟稳重的好男人 2021-12-01 17:58:06

默认构造方法是硬伤。。。用官方wiki说得另外一个库构造也不行。。。

把回忆走一遍 2021-12-01 17:53:48

so,还是不推荐在 j2cache 中使用

平生欢 2021-12-01 17:45:59

嗯  kryo依赖默认构造函数 或者构造函数,你那个测试用例 ,http://hi.baidu.com/macrohuang/item/70d84a6f9f1b11147ddecc90  啊 坑啊。 避免就避免吧 知道这个就行了

List<String> list= Arrays.asList("");

         List<String> stringList=new ArrayList<String>();

         System.out.println
                 ((list instanceof ArrayList)?"list is ArrayList"
                         :"list not ArrayList?");

         System.out.println
                 ((stringList instanceof ArrayList)?"list is ArrayList"
                         :"list not ArrayList?");

旧城烟雨 2021-12-01 17:39:49

回复
Java 标准序列化方法也没问题

终遇你 2021-12-01 17:39:40

嗯 构造函数惹祸。因为像我这边,序列化的对象都是诸如mybatis自己生成的对象,fastMap.FastTable,标准裤的ArrayList。所以都至少有一个默认构造函数 ,使用kryo避免这个问题就好 。性能上确实快。但是和fst比,100w次相差也不是很大。稳定第一,不跳坑。

恋你朝朝暮暮 2021-12-01 17:30:00

回复
注册一个实现类就可以了 kryo.register(Arrays.asList("").getClass(), new ArraysAsListSerializer()); https://github.com/magro/kryo-serializers 源代码在这里

复古式 2021-12-01 17:28:24

回复
FST 单线程下没有Kryo快. 而FST序列化后,字节码相对kryo要大4倍.

陌若浮生 2021-12-01 16:23:35

回复
cool ,got it!

瀞厅☆埖开 2021-12-01 16:08:05

不是推送了一个pr没看? asList---返回一个list接口,在kryo中 接口  抽象类是无法反 序列化的,

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文