【问题标题】:Kryo classloader issueKryo 类加载器问题
【发布时间】:2018-02-13 23:19:53
【问题描述】:

我有 2 个应用程序: Application1 使用 Kryo 序列化器序列化 Java 对象,而 application2 反序列化由 application1 保存在外部存储上的 kryo 序列化字节[]。

Application1 的类路径中有 kryo-shaded-3.0.3.jar,而 application2 的类路径中有 kryo-shaded-4.0.1。

当 application2 尝试对 byte[] 进行反序列化时,它会出现异常: kryo 无法使用 kryo 的类加载器加载类,正在使用当前重试。

当我将 application1 中的 kryo 版本更改为 kryo-shaded-4.0.1 时。它工作正常。为什么当序列化程序具有不同版本时会出现问题。 谁设置了 kryo 类加载器?

【问题讨论】:

  • 您会期望序列化格式在主要的 kryo 版本中有所不同。因此,至少为了兼容性,您需要使用相同的主要版本。

标签: java serialization kryo


【解决方案1】:

为什么当序列化器版本不同时会出现问题?

当 Kryo 将数据序列化为字节数组时,它会将对象的内容打包成特定的格式。 Kryo 将数据打包到不同 Kryo 版本的字节数组中的确切方式。因此,如果您使用 3.0.3 版本序列化数据,则格式将与 4.0.1 版本预期的格式不同。所以如果你以他不理解的格式向接收者发送字节,你就不能指望他正确处理数据。

谁设置了 kryo 类加载器?

我不确定 Kryo 的内部结构,但我认为它可能使用与默认运行代码的线程相同的类加载器。如果您愿意,您也许可以设置一个替代类加载器,但您必须查看文档。

您观察到的异常kryo unable to load class with Kryo's classloader retrying with current 很可能是因为接收方误读了发送给他的字节数组。例如,如果发送方发送了一个内容为com.my.class.TestXXXXXXX 的字节数组,其中类名在开头,但接收方希望类名在末尾,并将类名读取为XXXXXXX。然后 Kryo 会使用类加载器找到类XXXXXXX,但是他会失败,因为没有类XXXXXXX。为什么接收器上的 Kryo 需要首先查找类?因为他需要实例化您发送的 Object,为此他需要调用 Object 的 Class 的无参数构造函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-23
    • 2011-12-05
    • 2011-03-28
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    • 2011-08-05
    相关资源
    最近更新 更多