我有一个Spark (version 1.3.1)
申请。其中,我试图将一个Java bean RDD
JavaRDD<Message>
转换为Dataframe,它有许多具有不同数据类型的字段(整数,字符串,列表,地图,双精度)。
但是,当我执行我的代码时。
messages.foreachRDD(new Function2<JavaRDD<Message>,Time,Void>(){
@Override
public Void call(JavaRDD<Message> arg0, Time arg1) throws Exception {
SQLContext sqlContext = SparkConnection.getSqlContext();
DataFrame df = sqlContext.createDataFrame(arg0, Message.class);
df.registerTempTable("messages");
我收到了这个错误
/06/12 17:27:40 INFO JobScheduler: Starting job streaming job 1434110260000 ms.0 from job set of time 1434110260000 ms
15/06/12 17:27:40 ERROR JobScheduler: Error running job streaming job 1434110260000 ms.1
scala.MatchError: interface java.util.List (of class java.lang.Class)
at org.apache.spark.sql.SQLContext$$anonfun$getSchema$1.apply(SQLContext.scala:1193)
at org.apache.spark.sql.SQLContext$$anonfun$getSchema$1.apply(SQLContext.scala:1192)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:108)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
at scala.collection.mutable.ArrayOps$ofRef.map(ArrayOps.scala:108)
at org.apache.spark.sql.SQLContext.getSchema(SQLContext.scala:1192)
at org.apache.spark.sql.SQLContext.createDataFrame(SQLContext.scala:437)
at org.apache.spark.sql.SQLContext.createDataFrame(SQLContext.scala:465)
答案 0 :(得分:5)
如果Message
有许多不同的字段,例如List
,并且错误消息指向List
匹配错误,则问题就在于此问题。另外,如果您查看the source code,则可以看到List
不在匹配中。
但除了在源代码中进行挖掘之外,文档here under the Java tab中的非常清楚地说明:
目前,Spark SQL不支持包含嵌套或包含复杂类型(如Lists或Arrays)的JavaBean。
您可能希望切换到Scala,因为它似乎支持:
案例类也可以嵌套或包含复杂类型,如序列或数组。此RDD可以隐式转换为DataFrame,然后注册为表。
因此解决方案是使用Scala或从JavaBean中删除List
。
作为最后的手段,您可以查看SQLUserDefinedType来定义List
应该如何保留,也许可以一起破解它。
答案 1 :(得分:2)
我通过将我的Spark版本从1.3.1
更新为1.4.0
来解决了这个问题。现在,它工作文件。