如何修复java.lang.ClassCastException:无法将scala.collection.immutable.List的实例分配给字段类型scala.collection.Seq?

如何修复java.lang.ClassCastException:无法将scala.collection.immutable.List的实例分配给字段类型scala.collection.Seq?,java,apache-spark,spark-cassandra-connector,Java,Apache Spark,Spark Cassandra Connector,这个错误是最难追踪的。我不知道发生了什么事。我正在我的定位机上运行Spark群集。因此,整个spark cluster都在一台主机下,127.0.0.1,我以独立模式运行 JavaPairRDD<byte[], Iterable<CassandraRow>> cassandraRowsRDD= javaFunctions(sc).cassandraTable("test", "hello" ) .select("rowkey", "col1", "col2", "c

这个错误是最难追踪的。我不知道发生了什么事。我正在我的定位机上运行Spark群集。因此,整个spark cluster都在一台主机下,
127.0.0.1
,我以独立模式运行

JavaPairRDD<byte[], Iterable<CassandraRow>> cassandraRowsRDD= javaFunctions(sc).cassandraTable("test", "hello" )
   .select("rowkey", "col1", "col2", "col3",  )
   .spanBy(new Function<CassandraRow, byte[]>() {
        @Override
        public byte[] call(CassandraRow v1) {
            return v1.getBytes("rowkey").array();
        }
    }, byte[].class);

Iterable<Tuple2<byte[], Iterable<CassandraRow>>> listOftuples = cassandraRowsRDD.collect(); //ERROR HAPPENS HERE
Tuple2<byte[], Iterable<CassandraRow>> tuple = listOftuples.iterator().next();
byte[] partitionKey = tuple._1();
for(CassandraRow cassandraRow: tuple._2()) {
    System.out.println("************START************");
    System.out.println(new String(partitionKey));
    System.out.println("************END************");
}
以下是我使用的版本

Scala code runner version 2.11.8  // when I run scala -version or even ./spark-shell


compile group: 'org.apache.spark' name: 'spark-core_2.11' version: '2.0.0'
compile group: 'org.apache.spark' name: 'spark-streaming_2.11' version: '2.0.0'
compile group: 'org.apache.spark' name: 'spark-sql_2.11' version: '2.0.0'
compile group: 'com.datastax.spark' name: 'spark-cassandra-connector_2.11' version: '2.0.0-M3': 
我的gradle文件在引入了一个名为“provided”的东西后看起来是这样的,这个东西实际上似乎不存在,但谷歌说要创建一个,所以我的build.gradle看起来是这样的

group 'com.company'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'idea'

repositories {
    mavenCentral()
    mavenLocal()
}

configurations {
    provided
}
sourceSets {
    main {
        compileClasspath += configurations.provided
        test.compileClasspath += configurations.provided
        test.runtimeClasspath += configurations.provided
    }
}

idea {
    module {
        scopes.PROVIDED.plus += [ configurations.provided ]
    }
}

dependencies {
    compile 'org.slf4j:slf4j-log4j12:1.7.12'
    provided group: 'org.apache.spark', name: 'spark-core_2.11', version: '2.0.0'
    provided group: 'org.apache.spark', name: 'spark-streaming_2.11', version: '2.0.0'
    provided group: 'org.apache.spark', name: 'spark-sql_2.11', version: '2.0.0'
    provided group: 'com.datastax.spark', name: 'spark-cassandra-connector_2.11', version: '2.0.0-M3'
}



jar {
    from { configurations.provided.collect { it.isDirectory() ? it : zipTree(it) } }
   // with jar
    from sourceSets.test.output
    manifest {
        attributes 'Main-Class': "com.company.batchprocessing.Hello"
    }
    exclude 'META-INF/.RSA', 'META-INF/.SF', 'META-INF/*.DSA'
    zip64 true
}
方法应该返回字节[],如下所示

@Override
public byte[] call(CassandraRow v1) {
  return v1.getBytes("rowkey").array();
}

如果仍然存在问题,请检查Jira中提到的依赖项版本。我遇到了相同的异常,并深入研究了多个相关的Jira(,)

我认为异常名称令人困惑,真正的问题是spark cluster和驱动程序应用程序之间的环境设置不一致

例如,我用
conf/Spark defaults.conf
中的以下行启动了Spark集群:

spark.master                     spark://master:7077
当我启动我的驱动程序时(即使程序是用
spark submit
启动的),我用一行代码:

sparkSession.master("spark://<master ip>:7077")
sparkSession.master(“spark://:7077”)
其中
是节点
主节点的正确IP地址,但由于这种简单的不一致性,程序将失败


因此,我建议所有驱动程序应用程序都以
spark submit
启动,并且不要复制驱动程序代码中的任何配置(除非您需要覆盖某些配置)。也就是说,只需让spark提交
就可以在运行的spark集群中以相同的方式设置您的环境。

我也遇到了同样的问题,可以通过将我的应用程序的jar添加到spark的类路径来解决

spark = SparkSession.builder()
        .appName("Foo")
        .config("spark.jars", "target/scala-2.11/foo_2.11-0.1.jar")

在我的例子中,我必须添加
sparkavro
jar(我把它放在主jar旁边的
/lib
文件夹中):


检查您的代码-在Intellij中:分析…->检查代码。如果您有与序列化相关的弃用方法,请修复它。或者干脆尝试减少Spark o Scala版本。在我的例子中,我将Scala版本降低到2.10,并且所有的都工作了。

Hi!抱歉,我确实有.array(),我刚刚更新了问题。看起来我在粘贴代码的过程中出错了,但现在应该很好了。我也看到了那个链接,但我不知道那里发生了什么,这就是为什么我粘贴了我正在使用的所有版本。我使用的是Java 8,所以我不太懂scala的东西,也不明白标记库“提供”是什么意思。我测试了您的代码,它在spark 2.0.0的独立模式下运行良好。尝试清理构建环境、重建和测试。“提供的”依赖性意味着jar将在运行时可用。请检查您是否按照规定对其进行了标记?如果是这样的话,您标记了上面的哪些库提供了它们?我正在eclipse中使用maven依赖项运行spark java程序,所以我没有将它们标记为提供的。如果您希望使用spark submit在集群中运行构建jar,并且希望使用spark提供的jar,那么您可以将它们标记为已提供。请检查构建环境和集群环境中的jar文件和版本。我使用forking解决了这个问题,这对我来说很有效,但是为什么这是必要的呢?有人知道吗?如果真的需要的话,我希望spark能够自动解决这个问题。我认为,每当您使用lambda(引用项目的方法/类)执行任何类型的
map
操作时,您都需要将它们作为额外的jar提供。Spark确实序列化了lambda本身,但没有将其依赖项放在一起。不知道为什么错误消息没有提供任何信息。我不得不使用
spark.sparkContext.addJar(“lib/spark-avro_2.11-4.0.0.jar”)在我的情况下(括号已删除)。
spark = SparkSession.builder()
        .appName("Foo")
        .config("spark.jars", "target/scala-2.11/foo_2.11-0.1.jar")
SparkSession spark = SparkSession.builder().appName("myapp").getOrCreate();
...
spark.sparkContext().addJar("lib/spark-avro_2.11-4.0.0.jar");