【问题标题】:Apache Flink Kryo serializer - ClassNotFoundExceptionApache Flink Kryo 序列化程序 - ClassNotFoundException
【发布时间】:2020-10-17 14:08:47
【问题描述】:

我在 Apache Flink 1.8.1 中有一个项目,使用 Scala 2.11 和 Java 8。我曾经使用 Maven 进行编译和所有依赖项管理,但切换到 Gradle... 这导致我遇到以下问题:

j.l.ClassNotFoundException: om.tinker.my.project.ProjectPayload
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    ... 3 frames excluded
    at c.e.k.u.DefaultClassResolver.readName(DefaultClassResolver.java:172)
    ... 15 common frames omitted
    Wrapped by: c.e.kryo.KryoException: Unable to find class: om.tinker.my.project.ProjectPayload
    Serialization trace:
        eventOutputTag (com.my.project.contexts.ProjectContext)
        at c.e.k.u.DefaultClassResolver.readName(DefaultClassResolver.java:178)
        at c.e.k.u.DefaultClassResolver.readClass(DefaultClassResolver.java:147)
        at c.e.kryo.Kryo.readClass(Kryo.java:674)
        at c.e.k.s.ReflectField.read(ReflectField.java:107)
        at c.e.k.s.FieldSerializer.read(FieldSerializer.java:122)
        at c.e.kryo.Kryo.readClassAndObject(Kryo.java:793)
        at o.a.f.a.j.t.r.k.KryoSerializer.deserialize(KryoSerializer.java:346)
        at o.a.f.s.r.s.StreamElementSerializer.deserialize(StreamElementSerializer.java:202)
        at o.a.f.s.r.s.StreamElementSerializer.deserialize(StreamElementSerializer.java:46)
        at o.a.f.r.p.NonReusingDeserializationDelegate.read(NonReusin...

首先,错误消息缺少“c”。类路径应该是“com.tinker.my.project.ProjectPayload”...我使用该代码检查了文件,并且在我的导入语句中没有丢失“c”...

我还编辑了 Flink conf 文件以使用父优先策略...

更多背景信息: 我有另一个名为ProjectContext 的文件,它有一个ArrayList<ProjectPayload>。它还具有eventOutputTag(如序列化跟踪中所述)...当我注释掉ArrayList<ProjectPayload> 及其getter/setter 时,一切正常!

当我将实例变量及其 getter/setter 放回 ProjectContext 时,ClassNotFoundException 就会发生...

此外,我添加了大量的打印语句,我能够创建一个 ProjectPayload 实例,并将其很好地注销。

### 编辑(2020 年 6 月 30 日)###

鉴于this serialization issue,我添加了以下代码: env.getConfig.registerTypeWithKryoSerializer(classOf[ProjectPayload], classOf[JavaSerializer[ProjectPayload]])

现在我遇到了这个尴尬(但类似)的错误:

"j.l.ClassNotFoundException: \u0005sr\u00008com.tinker.my.project.ProjectPayload+\"v
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    ... 3 frames excluded
    at c.e.k.u.DefaultClassResolver.readName(DefaultClassResolver.java:172)
    ... 15 common frames omitted
    Wrapped by: c.e.kryo.KryoException: Unable to find class: \u0005sr\u00008com.tinker.my.project.ProjectPayload+\"v
    Serialization trace:
    allMyPayloads (com.tinker.my.project.ProjectContext)
    at c.e.k.u.DefaultClassResolver.readName(DefaultClassResolver.java:178)
    at c.e.k.u.DefaultClassResolver.readClass(DefaultClassResolver.java:147)
    at c.e.kryo.Kryo.readClass(Kryo.java:674)
    at c.e.k.s.ReflectField.read(ReflectField.java:107)
    at c.e.k.s.FieldSerializer.read(FieldSerializer.java:122)
    at c.e.kryo.Kryo.readClassAndObject(Kryo.java:793)
    at o.a.f.a.j.t.r.k.KryoSerializer.deserialize(KryoSerializer.java:346)
    at o.a.f.s.r.s.StreamElementSerializer.deserialize(StreamElementSerializer.java:202)
    at o.a.f.s.r.s.StreamElementSerializer.deserialize(StreamElementSerializer.java:46)
    at o.a.f.r.p.NonReusingDeserializationDelegate....
    

原来\u0005 是 unicode 字符“ENQUIRY”。 \u00008 导致 Google 搜索结果出现乱码...稍后会报告

### 编辑(2020 年 7 月 1 日)### 一些进展:我正在初始化ProjectContext 中的ArrayList<ProjectPayload>。当我删除那个初始化,把它移到外面,然后设置 ArrayList 值时,我的代码走得更远了。然后它还抱怨HashMap<String, String> 实例变量——我最终删除了它,因为它没有被使用。

现在把我带到IndexOutOfBoundsException

j.l.IndexOutOfBoundsException: Index: 93, Size: 9
    at java.util.ArrayList.rangeCheck(ArrayList.java:657)
    at java.util.ArrayList.get(ArrayList.java:433)
    at c.e.k.u.MapReferenceResolver.getReadObject(MapReferenceResolver.java:62)
    at c.e.kryo.Kryo.readReferenceOrNull(Kryo.java:838)
    at c.e.kryo.Kryo.readObjectOrNull(Kryo.java:761)
    at c.e.k.s.ReflectField.read(ReflectField.java:120)
    ... 12 common frames omitted
    Wrapped by: c.e.kryo.KryoException: java.lang.IndexOutOfBoundsException: Index: 93, Size: 9
    Serialization trace:
        fooBarStr (com.tinker.my.project.contexts.ProjectContext)
        at c.e.k.s.ReflectField.read(ReflectField.java:133)
        at c.e.k.s.FieldSerializer.read(FieldSerializer.java:122)
        at c.e.kryo.Kryo.readClassAndObject(Kryo.java:793)
        at o.a.f.a.j.t.r.k.KryoSerializer.deserialize(KryoSerializer.java:346)
        at o.a.f.s.r.s.StreamElementSerializer.deserialize(StreamElementSerializer.java:202)
        at o.a.f.s.r.s.StreamElementSerializer.deserialize(StreamElementSerializer.java:46)
        at o.a.f.r.p.NonReusingDeserializationDelegate.read(NonReusingDeserializationDelegate.java:55)
        at o.a.f.r.i.n.a.s.SpillingAdaptiveSpanningRecordDeserializer.getNextRecord(SpillingAdaptiveSpanningRec...

还有这个关于 Kryo 的 Github 问题:https://github.com/EsotericSoftware/kryo/issues/456

【问题讨论】:

  • 你可以尝试升级 Flink,也许升级到 1.8.3? 1.8.3 中至少修复了一个类加载器错误。
  • 感谢@davidAnderson 的提示。我已将问题缩小到 ArrayList 实例变量。我还发现我本地的 Flink 是 1.8.1,而 staging 中的 Flink 使用的是 Flink 1.8.3(发生错误的地方)。

标签: scala gradle serialization apache-flink kryo


【解决方案1】:

试试这个:

env.getConfig.registerTypeWithKryoSerializer(classOf[ProjectPayload], classOf[JavaSerializer[ProjectPayload]])
env.getConfig.registerTypeWithKryoSerializer(classOf[ProjectContext], classOf[JavaSerializer[ProjectContext]])

并确保您正在导入org.apache.flink.api.java.typeutils.runtime.kryo.JavaSerializer

https://ci.apache.org/projects/flink/flink-docs-stable/dev/custom_serializers.html#issue-with-using-kryos-javaserializer

【讨论】:

  • 是的,做到了。结果 Kryo 使用了默认的序列化程序 FieldSerializer,并在我的上下文类中对 ArrayList 和 HashMap 感到害怕。谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-06-29
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多