在浏览Google Cloud Dataflow WordCount Pipeline Example并创建Scala应用程序以在本地运行管道时,我遇到以下异常:
Exception in thread "main" java.lang.NullPointerException
at com.google.cloud.dataflow.sdk.util.SerializableUtils.clone(SerializableUtils.java:89)
at com.google.cloud.dataflow.sdk.transforms.ParDo$Bound.<init>(ParDo.java:700)
at com.google.cloud.dataflow.sdk.transforms.ParDo$Unbound.of(ParDo.java:661)
at com.google.cloud.dataflow.sdk.transforms.ParDo.of(ParDo.java:551)
at apps.MiniDataFlowApp$.delayedEndpoint$apps$MiniDataFlowApp$1(MiniDataFlowApp.scala:32)
at apps.MiniDataFlowApp$delayedInit$body.apply(MiniDataFlowApp.scala:17)
at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App$$anonfun$main$1.apply(App.scala:76)
at scala.App$$anonfun$main$1.apply(App.scala:76)
at scala.collection.immutable.List.foreach(List.scala:381)
at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
at scala.App$class.main(App.scala:76)
at apps.MiniDataFlowApp$.main(MiniDataFlowApp.scala:17)
at apps.MiniDataFlowApp.main(MiniDataFlowApp.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
其中MiniDataFlowApp.scala:32
对应于以下创建管道的代码段中的.apply(ParDo.of(extractWords))
:
val p: Pipeline = Pipeline.create(options)
p.apply(TextIO.Read.from("some.input.txt"))
.apply(ParDo.of(extractWords))
.apply(Count.perElement[String]())
.apply(ParDo.of(formatOutput))
.apply(TextIO.Write.to("some.output.txt"))
extractWords
按如下方式实施DoFn
:
val extractWords = new DoFn[String, String]() {
override def processElement(c: DoFn[String, String]#ProcessContext) {
c.element.split("[^a-zA-Z']+").filter(_.nonEmpty).map(_ => c.output(_))
}
}
this StackOverflow question中描述的问题似乎相似。但是,我不认为我有一个不可序列化的类,就像导致该问题的问题一样。至少,我不明白为什么我可能会遇到序列化问题,如果这就是问题。
感谢您抽出宝贵时间阅读我的问题和见解!
答案 0 :(得分:1)
这是一个初始化顺序问题。在Scala中,类主体中的val(对象是相应类的单例实例)按声明顺序初始化。
这意味着当p初始化时,extractWords和formatOutput没有,并且为null。 (我已经看到了OP代码的其余部分;那些成员是val之后的val。)
至少有3种解决方案:
1)更改val的顺序,使依赖项(extractWords,formatOutput)成为第一。
2)make extractWords和formatOutput lazy vals。这将使它们在被访问时被初始化,并保证它们只被初始化一次。
3)make extractWords和formatOutput defs。这将使他们在每次访问时重新计算,这可能会也可能不会。