Spark程序主函数注意
在scala程序中,主函数有两种启动方式:
object Test extends App {
//ToDo
}
object Test{
def main(args: Array[String]): Unit = {
//ToDo
}
}
其中第一种方法在Spark中不被兼容,可能会出现空指针异常,如下代码:
object Test extends App{
val conf = new SparkConf()
.setAppName("Test")
.set("spark.sql.tungsten.enabled", "true")
val sc = new SparkContext(conf)
val data = sc.parallelize(List(1, 2, 3, 4), 4)
val test_print = 111
val test_print2 = List("this", "is")
data.foreach(_ =>{
println("test1:", test_print)
println("test2:", test_print2)
})
}
运行后,对于第二个print出现如下空指针异常错误caused by: java.lang.NullPointerException
,且第一个print输出始终为0。
这是由于继承App后,里面所有变量都被认为是单个类的field了,并不会被初始化,无法被Spark访问到;而如果是以main函数初始化,所有变量都是被当作局部变量,这样一来,Spark程序封装闭包后便可以访问到该变量。
另外,Spark官方文档也有如下提示:
Note that applications should define a
main()
method instead of extendingscala.App
.Subclasses ofscala.App
may not work correctly.
因此,在使用Spark时,应注意Scala程序入口为main函数。