如何调试Flink中的可序列化异常?

时间:2017-12-22 18:05:27

标签: apache-flink flink-streaming flink-cep

我遇到了几个可序列化的例外,我在Flink的互联网和doc上做了一些搜索;有一些着名的解决方案,如transient,extends Serializable等。每次异常的起源都非常清楚,但在我的情况下,我无法找到它的确切位置。

问:我应该如何调试此类异常?

A.scala:

class executor ( val sink: SinkFunction[List[String]] {
    def exe(): Unit = {
        xxx.....addSink(sinks)
    }
}

B.scala:

class Main extends App {
  def createSink: SinkFunction[List[String]] = new StringSink()

  object StringSink {
    // static
    val stringList: List[String] = List()
  }

  // create a testing sink
  class StringSink extends SinkFunction[List[String]] {
    override def invoke(strs: List[String]): Unit = {
        // add strs into the variable "stringList" of the compagin object StringSink
    }
  }

  new executor(createSink()).exe()

  // then do somethings with the strings
}

例外是:

  

SinkFunction 的实现不可序列化。该   object可能包含或引用非可序列化字段。

我发现了两个可疑点:

  1. StringSink的实例将传递到另一个文件中。
  2. StringSink类中,它使用静态变量stringList 它的竞争对象。

2 个答案:

答案 0 :(得分:1)

我的第一个猜测是你在StringSink中没有没有参数构造函数

POJO类型Clipped from here

的规则

如果满足以下条件,Flink会将数据类型识别为POJO类型(并允许“按名称”字段引用):

  1. 该类是公共的和独立的(没有非静态内部类)
  2. 该类具有公共无参数构造函数
  3. 类中的所有非静态非瞬态字段(以及所有超类)都是公共的(和非最终的)或者具有公共getter和setter方法,该方法遵循getter的Java bean命名约定和setter方法。
  4. 只需添加一个无参数构造函数,然后重试

        class StringSink extends SinkFunction[List[String]] {
            public StringSink() {
            }
    
            @override def invoke(strs: List[String]): Unit = {
                // add strs into the variable "stringList" of the compagin object StringSink
            }
    }
    

答案 1 :(得分:1)

我遇到了类似的问题。过去需要很长时间才能找出哪些成员/对象不可序列化。异常日志确实没有用。

帮助我的是以下JVM选项,它可以在异常跟踪中启用更多详细信息。

启用此选项...

-Dsun.io.serialization.extendedDebugInfo =真