Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
找不到与产品对应的Java类,该产品具有可序列化的基类_Java_Scala_Apache Spark_Rdd_Apache Spark Dataset - Fatal编程技术网

找不到与产品对应的Java类,该产品具有可序列化的基类

找不到与产品对应的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[

我已经编写了两个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[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就不会推断出产品的
基。您的意思是,如果添加了产品
,它将无法工作?