Kryo 3.0 反序列化的问题
之前 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(19)
我用fst ,kyro很多bug
我已经找到原因了,不过可惜架构师换了缓存框架,放弃了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
HttpSession序列化? 应该是不行吧, 你能把HttpServletRequest对象序列化吗?同理的, HttpSession包含连接状态,如何能序列化呢。。。
晕得很, kryo 不能序列化 session 比如 变量类型是 serializable 的变量 ,kryo 无法序列化
回复
可以缓存
缓存的是settributes map,sessionId等信息,分布式运用
回复
@xchm :
架构师想用redis来缓存HttpSession,指定使用kryo作为序列化工具,我在实现的时候发现Kryo没办法反序列化HttpSession。不知道有没有其他的序列化工具好用点,另外使用EHcache+tc来缓存session和用redis来缓存session哪个好点
@红薯
默认构造方法是硬伤。。。用官方wiki说得另外一个库构造也不行。。。
so,还是不推荐在 j2cache 中使用
@红薯 yes 。
嗯 kryo依赖默认构造函数 或者构造函数,你那个测试用例 ,http://hi.baidu.com/macrohuang/item/70d84a6f9f1b11147ddecc90 啊 坑啊。 避免就避免吧 知道这个就行了
回复
Java 标准序列化方法也没问题
嗯 构造函数惹祸。因为像我这边,序列化的对象都是诸如mybatis自己生成的对象,fastMap.FastTable,标准裤的ArrayList。所以都至少有一个默认构造函数 ,使用kryo避免这个问题就好 。性能上确实快。但是和fst比,100w次相差也不是很大。稳定第一,不跳坑。
回复
注册一个实现类就可以了 kryo.register(Arrays.asList("").getClass(), new ArraysAsListSerializer()); https://github.com/magro/kryo-serializers 源代码在这里
回复
FST 单线程下没有Kryo快. 而FST序列化后,字节码相对kryo要大4倍.
回复
cool ,got it!
不是推送了一个pr没看? asList---返回一个list接口,在kryo中 接口 抽象类是无法反 序列化的,
@石头哥哥