【发布时间】:2019-09-18 09:51:43
【问题描述】:
Apache Beam 似乎拒绝识别 Kotlin 的 Iterable。这是一个示例代码:
@ProcessElement
fun processElement(
@Element input: KV<String, Iterable<String>>, receiver: OutputReceiver<String>
) {
val output = input.key + "|" + input.value.toString()
println("output: $output")
receiver.output(output)
}
我收到以下奇怪的错误:
java.lang.IllegalArgumentException:
...PrintString, @ProcessElement processElement(KV, OutputReceiver), @ProcessElement processElement(KV, OutputReceiver):
@Element argument must have type org.apache.beam.sdk.values.KV<java.lang.String, java.lang.Iterable<? extends java.lang.String>>
果然,如果我将Iterable 替换为java.lang.Iterable,同样的代码就可以正常工作。我做错了什么?
依赖的版本:
- kotlin-jvm:
1.3.21 - org.apache.beam:
2.11.0
这是一个包含完整代码和堆栈跟踪的要点:
更新:
经过一番反复试验,我发现虽然List<String> 会引发类似的异常,但MutableList<String> 确实有效:
class PrintString: DoFn<KV<String, MutableList<String>>, String>() {
@ProcessElement
fun processElement(
@Element input: KV<String, MutableList<String>>, receiver: OutputReceiver<String>
) {
val output = input.key + "|" + input.value.toString()
println("output: $output")
receiver.output(output)
}
}
所以,这提醒了我 Kotlin 的 Immutable 集合实际上只是接口,而底层集合仍然是可变的。但是,尝试将 Iterable 替换为 MutableIterable 会继续引发错误。
更新 2:
我使用上述MutableList 部署了我的 Kotlin Dataflow 作业,但作业失败:
java.lang.RuntimeException: org.apache.beam.sdk.util.UserCodeException: java.lang.ClassCastException:
org.apache.beam.runners.dataflow.worker.util.BatchGroupAlsoByWindowViaIteratorsFn$WindowReiterable cannot be cast to java.util.List
at org.apache.beam.runners.dataflow.worker.GroupAlsoByWindowsParDoFn$1.output(GroupAlsoByWindowsParDoFn.java:184)
at org.apache.beam.runners.dataflow.worker.GroupAlsoByWindowFnRunner$1.outputWindowedValue(GroupAlsoByWindowFnRunner.java:102)
我不得不切换回使用java.lang.Iterable。
【问题讨论】:
-
这是在运行时还是在编译时?你能分享更多的堆栈跟踪吗?
-
@mkobit 堆栈跟踪已添加到 gist.github.com/marcoslin/…。谢谢
标签: kotlin google-cloud-dataflow apache-beam