开发者社区> 问答> 正文

Kryo 3.0 反序列化的问题 400 请求报错 

之前 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

展开
收起
kun坤 2020-05-29 10:55:13 638 0
1 条回答
写回答
取消 提交回答
  • @石头哥哥 ###### 不是推送了一个pr没看? asList---返回一个list接口,在kryo中 接口  抽象类是无法反 序列化的, ######回复 @愚者00 : cool ,got it!######回复 @红薯 : FST 单线程下没有Kryo快. 而FST序列化后,字节码相对kryo要大4倍.######回复 @红薯 : 注册一个实现类就可以了 kryo.register(Arrays.asList("").getClass(), new ArraysAsListSerializer()); 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=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?");

    ######@红薯 yes 。######so,还是不推荐在 j2cache 中使用###### 默认构造方法是硬伤。。。用官方wiki说得另外一个库构造也不行。。。 ######架构师想用redis来缓存HttpSession,指定使用kryo作为序列化工具,我在实现的时候发现Kryo没办法反序列化HttpSession。不知道有没有其他的序列化工具好用点,另外使用EHcache+tc来缓存session和用redis来缓存session哪个好点 @红薯

    ######回复 @xchm :######缓存的是settributes map,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-05-29 12:01:26
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

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