2017-09-13 1 views
2

Le code suivant scala fonctionne très bien, et les séries de tests:Qu'est-ce qui cause une exception NullPointerException lorsqu'un SharedSparkContext (sc) est utilisé en dehors d'une fonction de test dans FunSuite?

import org.scalatest._ 
import com.holdenkarau.spark.testing._ 

class DummyTest extends FunSuite with SharedSparkContext { 
    test("shared context only works inside test functions.") { 
    val myRDD = sc.parallelize(List(1,2,3,4)) 
    } 
} 

Cependant, les résultats de code scala suivants dans un java.lang.NullPointerException sur la ligne sc.parallelize:

import org.scalatest._ 
import com.holdenkarau.spark.testing._ 

class DummyTest extends FunSuite with SharedSparkContext { 
    val myRDD = sc.parallelize(List(1,2,3,4)) 
    test("shared context only works inside test functions.") { 
     assert(true) 
    } 
} 

Qu'est-ce que provoque l'exception NullPointerException lorsque le SparkContext est utilisé en dehors de la fonction de test?

+0

Où est-ce que sc est déclaré? –

+0

Vous obtenez sc comme un champ de SharedSparkContext. Par exemple. https://github.com/zezutom/spark-by-example/blob/master/src/test/scala/basic/WordCountTest.scala –

+0

beforeAll dans SharedSparkContext est responsable de l'initialisation de sc qui ne se produit pas. Assurez-vous que la méthode beforeAll de super classe est exécutée en premier. –

Répondre

5

Le SparkContext est déclaré dans SharedSparkContext mais pas initialisé dans le cadre de l'initialisation de ce trait. Il est plutôt initialisé dans la méthode beforeAll() du trait, qui est appelée par le framework de test après que la suite a été entièrement instanciée. La source est ici: https://github.com/holdenk/spark-testing-base/blob/master/src/main/pre-2.0/scala/com/holdenkarau/spark/testing/SharedSparkContext.scala. Si vous l'utilisez lors de l'initialisation de votre classe, beforeAll() n'a pas encore été appelé, il est donc toujours nul.

Donc, pour résumer, l'ordre est:

  1. initialisation Super-classe (code juste dans le corps de trait)
  2. initialisation Sous-classe (code juste dans le corps de votre classe)
  3. beforeAll () appelé
  4. tests exécutés

vous pouvez donc utiliser sc à l'étape 4, mais pas à l'étape 2.