我在尝试解析我的火花工作中的json时遇到了问题。我使用spark 1.1.0
,json4s
和Cassandra Spark Connector
。抛出的异常是:
java.io.NotSerializableException: org.json4s.DefaultFormats
检查DefaultFormats伴随对象,并且使用此stack问题,很明显无法序列化DefaultFormats。问题是现在该做什么。
我可以看到ticket显然通过添加关键字transient来解决此问题,但我不确定如何或在何处将其应用于我的案例。解决方案是仅在执行程序上实例化DefaultFormats类,以避免序列化在一起吗?是否有人们正在使用scala / spark的另一个JSON解析库?我最初尝试使用jackson本身,但遇到了一些我无法轻易解决的注释错误,json4s开箱即用。这是我的代码:
import org.json4s._
import org.json4s.jackson.JsonMethods._
implicit val formats = DefaultFormats
val count = rdd.map(r => checkUa(r._2, r._1)).reduce((x, y) => x + y)
我在checkUa函数中进行json解析。我试图让计数懒惰,希望它以某种方式延迟执行,但它没有效果。也许在checkUA中移动隐式val?任何建议都非常感谢。
答案 0 :(得分:16)
an open ticket with json4s已经回答了这个问题。解决方法是将implicit
声明放在函数
val count = rdd
.map(r => {implicit val formats = DefaultFormats; checkUa(r._2, r._1)})
.reduce((x, y) => x + y)
答案 1 :(得分:3)
当我将implicit val formats = ...
声明放在包含解析的方法中时,我遇到了同样的错误,而不是在类(对象)上声明它。
所以这会引发错误:
object Application {
//... Lots of other code here, which eventually calls
// setupStream(...)
def setupStream(streamingContext: StreamingContext,
brokers: String,
topologyTopicName: String) = {
implicit val formats = DefaultFormats
_createDStream(streamingContext, brokers, topologyTopicName)
// Remove the message key, which is always null in our case
.map(_._2)
.map((json: String) => parse(json).camelizeKeys
.extract[Record[TopologyMetadata, Unused]])
.print()
}
但这没关系:
object Application {
implicit val formats = DefaultFormats
//... Lots of other code here, which eventually calls
// setupStream(...)
def setupStream(streamingContext: StreamingContext,
brokers: String,
topologyTopicName: String) = {
_createDStream(streamingContext, brokers, topologyTopicName)
// Remove the message key, which is always null in our case
.map(_._2)
.map((json: String) => parse(json).camelizeKeys
.extract[Record[TopologyMetadata, Unused]])
.print()
}