错误日志
Exception in thread "main" org.apache.spark.SparkException: Task not serializable
//中间省略很多行报错信息
- object (class org.apache.spark.sql.catalyst.expressions.ScalaUDF, UDF:merger(input[1, string, true], input[3, string, true]))
- element of array (index: 0)
- array (class [Ljava.lang.Object;, size 1)
- field (class: org.apache.spark.sql.execution.WholeStageCodegenExec$$anonfun$8, name: references$1, type: class [Ljava.lang.Object;)
日志分析
从代码中可以看出
1.任务不能序列化
2.UDF自定义函数中返回的数组为空
错误代码
spark.udf.register("merge",(newTagsid:String,oldTagsId:String)=>{
if (StringUtils.isBlank(newTagsid)) {
return oldTagsId
}else if (StringUtils.isBlank(oldTagsId)) {
return newTagsid
} else{
val oldArr: Array[String] = oldTagsId.split(",")
val newArr: Array[String] = newTagsid.split(",")
val tagsIdArr: Array[String] = newArr ++ oldArr
/*去重*/
val tagsIdSet: Set[String] = tagsIdArr.toSet
/*转为String,并用,分割*/
val tagsId: String = tagsIdSet.mkString(",")
tagsId
}
})
//下边会有方法调用
代码分析
1.前提条件:方法调用时,参数值是不为空的,有值的.可以通过事先打印确认
2.明明参数不为空,数组确无法接收参数值的原因是什么?
3.原因:return会被解释成抛出异常
4.这里我们就要问了,在什么情况下return会被解释成抛出异常呢?
5.那就是return出现在非命名闭包里的时候,比如我们常见的lambda表达式里。
一旦这些地方出现了return,那么它就被赋予了退出其所在的外层函数的使命.
如果一直到不了外层函数并且未被捕获,那么它可能会终止你的线程。
报错原因分析参考链接
慎用Scala中的return表达式
The return keyword is not “optional” or “inferred”;
it changes the meaning of your program, and you should never use it.
改正方法
1.删除所有return
2.上次话提示.应该不使用return