找不到与产品对应的Java类,该产品具有可序列化的基类
我已经编写了两个case类,扩展了Base找不到与产品对应的Java类,该产品具有可序列化的基类,java,scala,apache-spark,rdd,apache-spark-dataset,Java,Scala,Apache Spark,Rdd,Apache Spark Dataset,我已经编写了两个case类,扩展了Base抽象类。每个类有两个列表(listA和listB)。当我想要合并这两个列表时,我无法将最终列表转换为ApacheSpark1.6.1数据集 abstract class Base case class A(name: String) extends Base case class B(age: Int) extends Base val listA: List[A] = A("foo")::A("bar")::Nil val listB: List[
抽象类
。每个类有两个列表(listA
和listB
)。当我想要合并这两个列表时,我无法将最终列表转换为ApacheSpark1.6.1数据集
abstract class Base
case class A(name: String) extends Base
case class B(age: Int) extends Base
val listA: List[A] = A("foo")::A("bar")::Nil
val listB: List[B] = B(10)::B(20)::Nil
val list: List[Base with Product with Serializable] = listA ++ listB
val result: RDD[Base with Product with Serializable] = sc.parallelize(list).toDS()
Apache Spark将引发此异常:
A needed class was not found. This could be due to an error in your runpath. Missing class: no Java class corresponding to Base with Product with Serializable found
java.lang.NoClassDefFoundError: no Java class corresponding to Base with Product with Serializable found
at scala.reflect.runtime.JavaMirrors$JavaMirror.typeToJavaClass(JavaMirrors.scala:1299)
at scala.reflect.runtime.JavaMirrors$JavaMirror.runtimeClass(JavaMirrors.scala:192)
at scala.reflect.runtime.JavaMirrors$JavaMirror.runtimeClass(JavaMirrors.scala:54)
at org.apache.spark.sql.catalyst.encoders.ExpressionEncoder$.apply(ExpressionEncoder.scala:50)
at org.apache.spark.sql.SQLImplicits.newProductEncoder(SQLImplicits.scala:41)
当我想从
list
创建RDD时,Spark不会抛出任何异常,但当我使用toDS()
方法将RDD转换为Dataset时,前面的异常将抛出。首先,您可以通过将list
设置为list[Base]来获得一个更合理的类型
如果只想通过案例类/对象扩展产品,则显式地或通过添加Base extensed Product with Serializable
。但这还不够,因为
请注意,不支持像Base
这样的抽象类。自定义编码器也不受支持。尽管您可以尝试使用kryo
(或javaSerialization
,作为最后手段)编码器,请参阅
以下是完整的工作示例:
abstract class Base extends Serializable with Product
case class A(name: String) extends Base
case class B(age: Int) extends Base
object BaseEncoder {
implicit def baseEncoder: org.apache.spark.Encoder[Base] = org.apache.spark.Encoders.kryo[Base]
}
val listA: Seq[A] = Seq(A("a"), A("b"))
val listB: Seq[B] = Seq(B(1), B(2))
val list: Seq[Base] = listA ++ listB
val ds = sc.parallelize(list).toDS
我不确定数据集编码器是否支持混入。tait解决方案不起作用,但编写编码器效果很好。第二段实际上解释了为什么第一段还不够。我修改了文本以使其更清晰。这样,如果您没有为
列表
(或其他地方)指定类型,Scala就不会推断出产品的基。您的意思是,如果添加了产品
,它将无法工作?