2017-02-07 1 views
3

Je teste une étincelle streaming d'application avec l'aide de "com.holdenkarau.spark-test base" et scalatest.

import com.holdenkarau.spark.testing.StreamingSuiteBase 
import org.apache.spark.rdd.RDD 
import org.scalatest.{ BeforeAndAfter, FunSuite } 

class Test extends FunSuite with BeforeAndAfter with StreamingSuiteBase { 

    var delim: String = "," 

    before { 
    System.clearProperty("spark.driver.port") 
    } 

    test(“This Fails“) { 

    val source = scala.io.Source.fromURL(getClass.getResource(“/some_logs.csv")) 
    val input = source.getLines.toList 

    val rowRDDOut = Calculator.do(sc.parallelize(input)) //Returns DataFrame 

    val report: RDD[String] = rowRDDOut.map(row => new String(row.getAs[String](0) + delim + row.getAs[String](1)) 

    source.close 
    } 
} 

Je reçois exception sérialisation pour le champ 'delim':

org.apache.spark.SparkException: Task not serializable 
[info] at org.apache.spark.util.ClosureCleaner$.ensureSerializable(ClosureCleaner.scala:304) 
[info] at org.apache.spark.util.ClosureCleaner$.org$apache$spark$util$ClosureCleaner$$clean(ClosureCleaner.scala:294) 
[info] at org.apache.spark.util.ClosureCleaner$.clean(ClosureCleaner.scala:122) 
[info] at org.apache.spark.SparkContext.clean(SparkContext.scala:2055) 
[info] at org.apache.spark.rdd.RDD$$anonfun$map$1.apply(RDD.scala:324) 
[info] at org.apache.spark.rdd.RDD$$anonfun$map$1.apply(RDD.scala:323) 
[info] at org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:150) 
[info] at org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:111) 
[info] at org.apache.spark.rdd.RDD.withScope(RDD.scala:316) 
[info] at org.apache.spark.rdd.RDD.map(RDD.scala:323) 
[info] ... 
[info] Cause: java.io.NotSerializableException: org.scalatest.Assertions$AssertionsHelper 
[info] Serialization stack: 
[info] - object not serializable (class: org.scalatest.Assertions$AssertionsHelper, value: [email protected]) 
[info] - field (class: org.scalatest.FunSuite, name: assertionsHelper, type: class org.scalatest.Assertions$AssertionsHelper) 

Si je remplace 'delim' par la valeur chaîne en place, il fonctionne très bien.

val report: RDD[String] = rowRDDOut.map(row => new String(row.getAs[String](0) + “,” + row.getAs[String](1)) 

Quelle est la différence entre la première et la deuxième version?

Merci d'avance!

Répondre

4

Le problème n'est pas le type de delim (Chaîne) c'est delim lui-même. Essayez de ne pas définir de variables en dehors de vos méthodes test(). Si vous définissez delm à l'intérieur de votre test cela devrait fonctionner.

test(“This Fails“) { 
    val delim = "," 
    ... 
} 

Maintenant, vous pouvez vous demander pourquoi? Eh bien, lorsque vous référencez delim à partir de la portée externe, Scala essayera de rassembler l'objet englobant class Test. Cet objet contient une référence à org.scalatest.Assertions$AssertionsHelper que ce n'est pas Serializable (voir votre stacktrace).

+1

Whoa Monsieur! Je ne pouvais même pas penser ça! Merci! Travaillé comme un charme. –