scala java.lang.NullPointerException

时间:2017-11-01 03:41:08

标签: scala apache-spark

以下代码导致java.lang.NullPointerException。

val sqlContext = new SQLContext(sc)
val dataFramePerson = sqlContext.read.format("com.databricks.spark.csv").option("header", "true").schema(CustomSchema1).load("c:\\temp\\test.csv")
val dataFrameAddress = sqlContext.read.format("com.databricks.spark.csv").option("header", "true").schema(CustomSchema2).load("c:\\temp\\test2.csv")

val personData = dataFramePerson.map(data => {
  val addressData = dataFrameAddress.filter(i => i.getAs("ID") == data.getAs("ID"));
  var address:Address = null;
  if (addressData != null) {
    val addressRow = addressData.first;
    address = addressRow.asInstanceOf[Address];
  }
  Person(data.getAs("Name"),data.getAs("Phone"),address)
})

我把它缩小到导致异常的下一行。

val addressData = dataFrameAddress.filter(i => i.getAs("ID") == data.getAs("ID"));

有人可以指出问题是什么吗?

2 个答案:

答案 0 :(得分:3)

您的代码存在很大的结构缺陷,也就是说,您只能从驱动程序中执行的代码中引用数据帧,而不能在执行程序运行的代码中引用。您的代码包含对映射中另一个数据帧的引用,该数据帧在执行程序中执行。请参阅此链接Can I use Spark DataFrame inside regular Spark map operation?

val personData = dataFramePerson.map(data => { // WITHIN A MAP
  val addressData = dataFrameAddress.filter(i => // <--- REFERRING TO OTHER DATAFRAME WITHIN A MAP
          i.getAs("ID") == data.getAs("ID"));  
  var address:Address = null;
  if (addressData != null) {

您想要做的是左外连接,然后进行进一步处理。

dataFramePerson.join(dataFrameAddress, Seq("ID"), "left_outer")

请注意,使用getAs时要指定类型,例如getAs[String]("ID")

答案 1 :(得分:0)

唯一可以说是dataFrameAddressidatanull。使用您最喜欢的调试技术来了解实际的调试技术,例如调试器,打印语句或日志。

请注意,如果您在filter的堆栈跟踪中看到NullPointerException来电,则表示只有idata可能是null 。另一方面,如果您没有看到filter来电,则表示它是dataFrameAddress null