使用Scala在带有Spark-shell的Option [T] arg类型中将JSON解析为类

时间:2018-05-25 22:52:36

标签: json scala jackson

我在使用spark-shell中的json4s.jackson解析JSON时遇到问题。同样的事情在sbt repl中工作正常。

我想知道我使用的Spark版本是否有解决方法。

  • spark-shell v1.6,scala v2.10.5
  • sbt repl scala v 2.11.8

以下示例演示了此问题。

  • sbt repl适用于所有示例。
  • spark-shell chokes并为val c提供错误。奇怪的是它似乎在Option[Int]Option[Double]上窒息,但它适用于Option[A],其中A是一个类。

import org.json4s.JsonDSL._
import org.json4s.jackson.JsonMethods.{render,compact,pretty}

import org.json4s.DefaultFormats
import org.json4s.jackson.JsonMethods._
import org.json4s.{JValue, JObject} 

implicit val formats = DefaultFormats


class A(val a: Int, val aa: Int)
class B(val b: Int, val optA: Option[A]=None)
class C(val b: Int, val bb: Option[Int]=None)

val jb_optA_nested: JObject     = ("b" -> 5) ~ ("optA" -> ("a" -> 999) ~ ("aa" -> 1000))
val jb_optA_not_nested: JObject = ("b" -> 5) ~ ("a" -> 999) ~ ("aa" -> 1000)
val jb_optA_none: JObject       = ("b" -> 5)
val jc: JObject                 = ("b" -> 5) ~ ("bb" -> 100)


val b_nested     = jb_optA_nested.extract[B]      // works as expected in both (optA=Some(A(999,1000)))
val b_not_nested = jb_optA_not_nested.extract[B]  // works as expected in both (optA=None)
val b_none       = jb_optA_none.extract[B]        // works as expected in both (optA=None)
val c            = jc.extract[C]                  // error in spark-shell; works fine in sbt repl

生成的错误是:org.json4s.package$MappingException: Can't find constructor for C

我能找到的唯一真正的区别(除了scala版本)是在spark-shell中......它在Option [native types]上窒息而且似乎适用于Option [用户定义的类]。但也许这是巧合。

在这样的帖子中...... JSON4s can't find constructor w/spark我看到人们建议类结构与JSON不匹配的评论......但对我来说,class Cval jc看起来完全相同

另外值得注意的是......当我在.JAR中强化类defs和函数并从jar中导入defs到spark-shell而不是在repl中定义时,这个错误仍然存​​在。有时这与火花1.6有关,但似乎不在这里。

1 个答案:

答案 0 :(得分:1)

你试过了吗?

class C(val b: Int, val bb: Option[java.lang.Integer]=None)

我之前在使用Json4s时遇到了Scala Int的问题 - 虽然我无法回想起它是什么。

使用case class进行Int是值得的 - 您是否更喜欢常规的class?我没有看到任何var