Spark上有json4s的NotSerializableException

Spark上有json4s的NotSerializableException,json,scala,hdfs,apache-spark,json4s,Json,Scala,Hdfs,Apache Spark,Json4s,基本上,我必须使用Spark分析HDFS上的一些复杂JSON 我使用“for comprehensions”来(预)过滤JSON和“extract”方法 将json4s封装到case类中 这个很好用 def foo(rdd: RDD[String]) = { case class View(C: String,b: Option[Array[List[String]]], t: Time) case class Time($numberLong: String) implicit val f

基本上,我必须使用Spark分析HDFS上的一些复杂JSON

我使用“for comprehensions”来(预)过滤JSON和“extract”方法 将json4s封装到case类中

这个很好用

def foo(rdd: RDD[String]) = {

case class View(C: String,b: Option[Array[List[String]]],  t: Time)
case class Time($numberLong: String)
implicit val formats = DefaultFormats

rdd.map { jsonString =>
  val jsonObj = parse(jsonString)
  val listsOfView = for {
    JObject(value) <- jsonObj
    JField(("v"), JObject(views)) <- value
    normalized <- views.map(x => (x._2))
  } yield normalized
}
def foo(rdd:rdd[String])={
案例类视图(C:String,b:Option[Array[List[String]],t:Time)
案例课堂时间($numberLong:String)
隐式val格式=默认格式
rdd.map{jsonString=>
val jsonObj=parse(jsonString)
val listsOfView=for{

JObject(value)Spark序列化RDD转换上的闭包,并将这些闭包“发送”给Worker以供分布式执行。 这要求闭包中的所有代码(通常也包括包含对象中的代码)都应该是可序列化的

看着(该特征的伴生对象)的impl:

很明显,这个对象是不可序列化的,并且不能这样做。(ThreadLocal本身就是不可序列化的)

您似乎没有在代码中使用
Date
类型,因此您可以删除这些类型吗
implicit val formats=DefaultFormats
或者用可序列化的东西替换DefaultFormats?

这实际上已经被修复;JSON4S从3.3.0版开始是可序列化的:

解决我的问题的是,我在
rdd.foreach{}中使用了
implicit val formats=DefaultFormats
loop。它解决了我的可序列化异常

以下是解决问题的代码片段:

case class rfId(rfId: String) {}

// ... some code here ...

 rdd.foreach { record =>
    val value = record.value()

    // Bring in default date formats etc and makes json4s serializable
    implicit val formats = DefaultFormats
    val json = parse(value)
    println(json.camelizeKeys.extract[rfId])  // Prints `rfId(ABC12345678)`
 }

请参阅,但是JSON4S 3.3与任何Spark版本都不兼容,除非您对依赖项进行着色,因为二进制/运行时与包含Spark的JSON4S 3.2不兼容。
object DefaultFormats extends DefaultFormats {
    val losslessDate = new ThreadLocal(new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"))
    val UTC = TimeZone.getTimeZone("UTC")

}
case class rfId(rfId: String) {}

// ... some code here ...

 rdd.foreach { record =>
    val value = record.value()

    // Bring in default date formats etc and makes json4s serializable
    implicit val formats = DefaultFormats
    val json = parse(value)
    println(json.camelizeKeys.extract[rfId])  // Prints `rfId(ABC12345678)`
 }