web-dev-qa-db-ja.com

Java.lang.ClassCastExceptionを修正する方法:scala.collection.immutable.Listのインスタンスをフィールドタイプscala.collection.Seqに割り当てることができませんか?

このエラーは、追跡が最も困難でした。何が起こっているのかわかりません。私はSparkクラスタをロケーションマシンで実行しています。そのため、sparkクラスタは、_127.0.0.1_という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************");
}
_

このエラーは、追跡が最も困難でした。それは明らかにcassandraRowsRDD.collect()で発生し、なぜなのかわかりませんか?

_16/10/09 23:36:21 ERROR Executor: Exception in task 2.3 in stage 0.0 (TID 21)
Java.lang.ClassCastException: cannot assign instance of scala.collection.immutable.List$SerializationProxy to field org.Apache.spark.rdd.RDD.org$Apache$spark$rdd$RDD$$dependencies_ of type scala.collection.Seq in instance of org.Apache.spark.rdd.MapPartitionsRDD
    at Java.io.ObjectStreamClass$FieldReflector.setObjFieldValues(ObjectStreamClass.Java:2133)
    at Java.io.ObjectStreamClass.setObjFieldValues(ObjectStreamClass.Java:1305)
    at Java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.Java:2006)
    at Java.io.ObjectInputStream.readSerialData(ObjectInputStream.Java:1924)
    at Java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.Java:1801)
    at Java.io.ObjectInputStream.readObject0(ObjectInputStream.Java:1351)
    at Java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.Java:2000)
    at Java.io.ObjectInputStream.readSerialData(ObjectInputStream.Java:1924)
    at Java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.Java:1801)
    at Java.io.ObjectInputStream.readObject0(ObjectInputStream.Java:1351)
    at Java.io.ObjectInputStream.readObject(ObjectInputStream.Java:371)
    at org.Apache.spark.serializer.JavaDeserializationStream.readObject(JavaSerializer.scala:75)
    at org.Apache.spark.serializer.JavaSerializerInstance.deserialize(JavaSerializer.scala:114)
    at org.Apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:66)
    at org.Apache.spark.scheduler.Task.run(Task.scala:85)
    at org.Apache.spark.executor.Executor$TaskRunner.run(Executor.scala:274)
    at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1142)
    at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:617)
    at Java.lang.Thread.run(Thread.Java:745)
_

ここに私が使用するバージョンがあります

_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ファイルは、実際には存在しないように見える「提供された」と呼ばれるものを導入した後、次のようになりますが、Googleはそれを作成すると言ったので、私の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
}
_
10
user1870400

私は同じ問題を抱えていましたが、アプリケーションのjarをsparkのクラスパスに追加することで解決できました

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

同じ例外が発生し、関連する複数のJiraに掘り下げました( 92191267518075 )。

例外名はわかりにくいと思いますが、実際の問題は、sparkクラスターとドライバーアプリケーションの間の矛盾した環境設定です。

たとえば、Sparkクラスターをconf/spark-defaults.confの次の行で開始しました:

spark.master                     spark://master:7077

ドライバープログラムを開始している間(プログラムがspark-submitで開始されている場合でも)、次の行を使用しています。

sparkSession.master("spark://<master ip>:7077")

ここで、<master ip>はノードmasterの正しいIPアドレスですが、この単純な不整合が原因でプログラムは失敗します。

その結果、すべてのドライバーアプリケーションはspark-submitで開始し、ドライバーコードの構成を複製しないことをお勧めします(構成をオーバーライドする必要がない限り)。つまり、実行中のSparkクラスタで同じ方法でspark-submitに環境を設定させるだけです。

4
Ambling

Call()メソッドは次のようにbyte []を返す必要があります。

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

それでも問題が発生する場合は、Jiraに記載されているように依存関係のバージョンを確認してください https://issues.Apache.org/jira/browse/SPARK-9219

1
abaghel

コードの確認-Intellijの場合:分析...->コードを検査します。シリアル化に関連する非推奨のメソッドがある場合は、それを修正してください。または、単純にSpark o Scala versionです。私の場合、Scala versionを2.10に減らし、すべてが機能しました。

0
Valeriy K.

私の場合、spark-avro jarを追加する必要がありました(メインjarの隣の/libフォルダーに入れました):

SparkSession spark = SparkSession.builder().appName("myapp").getOrCreate();
...
spark.sparkContext().addJar("lib/spark-avro_2.11-4.0.0.jar");
0
Nikita Bosik