开发者社区> 问答> 正文

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

展开
收起
爱吃鱼的程序员 2020-06-14 21:25:03 1476 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

    @石头哥哥

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

    回复 @愚者00:cool,gotit!回复 @红薯:FST单线程下没有Kryo快.而FST序列化后,字节码相对kryo要大4倍.回复 @红薯:注册一个实现类就可以了kryo.register(Arrays.asList("").getClass(),newArraysAsListSerializer());https://github.com/magro/kryo-serializers源代码在这里​嗯构造函数惹祸。因为像我这边,序列化的对象都是诸如mybatis自己生成的对象,fastMap.FastTable,标准裤的ArrayList。所以都至少有一个默认构造函数,使用kryo避免这个问题就好。性能上确实快。但是和fst比,100w次相差也不是很大。稳定第一,不跳坑。回复 @石头哥哥:Java标准序列化方法也没问题

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

    List<String>list=Arrays.asList("");List<String>stringList=newArrayList<String>();System.out.println((listinstanceofArrayList)?"listisArrayList":"listnotArrayList?");System.out.println((stringListinstanceofArrayList)?"listisArrayList":"listnotArrayList?");



    @红薯yes。so,还是不推荐在j2cache中使用

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

    架构师想用redis来缓存HttpSession,指定使用kryo作为序列化工具,我在实现的时候发现Kryo没办法反序列化HttpSession。不知道有没有其他的序列化工具好用点,另外使用EHcache+tc来缓存session和用redis来缓存session哪个好点 @红薯
    回复 @xchm:缓存的是settributesmap,sessionId等信息,分布式运用晕得很,kryo不能序列化session比如变量类型是serializable的变量,kryo无法序列化回复 @i仅此而已:可以缓存HttpSession序列化?应该是不行吧,你能把HttpServletRequest对象序列化吗?同理的,HttpSession包含连接状态,如何能序列化呢。。。我已经找到原因了,不过可惜架构师换了缓存框架,放弃了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我用fst,kyro很多bug
    2020-06-14 21:25:18
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载