在多台计算机上使用spark-submit运行spark项目时获取“java.lang.NoClassDefFoundError”

时间:2017-05-12 04:55:16

标签: object apache-spark methods jar noclassdeffounderror

我是scala / spark的初学者,在将我的代码发送到官方环境时我遇到了困难。

简而言之,我不能将我的SparkSession对象放在类方法中,我不知道为什么?如果我这样做,当我在本地单机上运行它时会很好,但是当我将代码打包到一个jar文件并使用spark-submit在多台机器上运行它时抛出java.lang.NoClassDefFoundError, Could not initialize class XXX

例如

当我把代码放在这样的结构中时

object Main{
    def main(...){
        Task.start
    }
} 

object Task{
    case class Data(name:String, ...)
    val spark = SparkSession.builder().appName("Task").getOrCreate()
    import spark.implicits._

    def start(){
        var ds = loadFile(path) 
        ds.map(someMethod) // it dies here!
    }

    def loadFile(path:String){
        spark.read.schema(...).json(path).as[Data]
    }

    def someMethod(d:Data):String{
        d.name
    }
}

在我将自定义方法放在那些数据集转换函数(如map,filter等)的每个地方都会给我“java.lang.NoClassDefFoundError”。

但是,如果我将其重写为

object Task{
    case class Data(name:String, ...)

    def start(){
        val spark = SparkSession.builder().appName("Task").getOrCreate()
        import spark.implicits._
        var ds = loadFile(spark, path) 
        ds.map(someMethod) // it works!
    }

    def loadFile(spark:SparkSession, path:String){
        import spark.implicits._
        spark.read.schema(...).json(path).as[Data]
    }

    def someMethod(d:Data):String{
        d.name
    }
}

没关系,但这意味着我需要通过我需要的每个方法传递“spark”变量,并且当方法需要时我需要一直编写import spark.implicits._。 / p>

当火花试图在节点之间移动我的对象时,我认为出现了问题,但我不知道原因究竟是什么以及编写代码的正确方法是什么。

由于

1 个答案:

答案 0 :(得分:0)

不,您不需要传递sparkSession个对象并导入implicits所需的所有方法。您可以将sparkSession变量作为函数外部的对象变量,并在所有函数中使用。

以下是您的代码的修改示例

object Main{
  def main(args: Array[String]): Unit = {
    Task.start()
  }
}

object Task{

  case class Data(fname:String, lname : String)
  val spark = SparkSession.builder().master("local").appName("Task").getOrCreate()

  import spark.implicits._

  def start(){
    var ds = loadFile("person.json")
    ds.map(someMethod).show()

  }

  def loadFile(path:String): Dataset[Data] = {
    spark.read.json(path).as[Data]
  }

  def someMethod(d:Data):String = {
    d.fname
  }
}

希望这有帮助!