我有2个申请: Application1使用Kryo序列化器序列化Java对象,application2将由application1保存的kryo序列化byte []反序列化到外部存储器上。
Application1在其类路径中有kryo-shaded-3.0.3.jar,而application2在其类路径中有kryo-shaded-4.0.1。
当application2尝试对byte []进行deserilze时,它会获得异常: kryo无法使用kryo的类加载器加载类,并使用当前重试。
当我将application1中的kryo版本更改为kryo-shaded-4.0.1时。它工作正常。当序列化程序具有不同版本时,为什么会出现问题。 谁设置了kryo类加载器?
答案 0 :(得分:0)
当Kryo将数据序列化为字节数组时,它会将对象的内容打包成特定格式。 Kryo在不同版本的Kryo中将数据打包成字节数组的确切方式。因此,如果使用3.0.3版序列化数据,则格式将与版本4.0.1预期的格式不同。因此,如果您以他不理解的格式向接收者发送字节,您就不能指望他正确处理数据。
我不确定Kryo的内部结构,但我认为它可能使用与默认运行代码的线程相同的类加载器。如果需要,您可以设置备用类加载器,但是您必须检查文档。
您观察到的异常kryo unable to load class with Kryo's classloader retrying with current
可能是由于接收方误读了发送给他的字节数组而引起的。例如,如果发送方发送了一个内容为com.my.class.TestXXXXXXX
的字节数组,其中类名称位于开头,但接收方希望类名称位于末尾,并将类名称读为XXXXXXX
。然后Kryo将使用类加载器来查找类XXXXXXX
,但他将失败,因为没有类XXXXXXX
。为什么接收器上的Kryo需要首先查找课程?因为他需要实例化你发送的对象,为了做到这一点,他需要调用Object的类的无参数构造函数。