NPE in spray-json because of recursive implicits (context bound issue?)

末鹿安然 提交于 2020-01-04 05:22:09

问题


Perhaps I discovered a bug in spray-json. I get Null Pointer Exception when I'm trying to get json of an object that has field of type of itself. Example is:

case class TestItem(subitems: Option[List[TestItem]])

object MyJsonProtocol extends DefaultJsonProtocol {
  implicit val testItemFormat: RootJsonFormat[TestItem] = jsonFormat(TestItem, "subitems")
}

import MyJsonProtocol._

object TestNPE {
  def main(args: Array[String]) {

    val subitems = List(TestItem(None))
    val item: TestItem = TestItem(Option(subitems))
    val jsonAst = item.toJson
    val json = jsonAst.prettyPrint
    println(json)
  }
}

And call-stack is this

Exception in thread "main" java.lang.NullPointerException
    at spray.json.PimpedAny.toJson(package.scala:40)
    at spray.json.CollectionFormats$$anon$1$$anonfun$write$1.apply(CollectionFormats.scala:26)
    at spray.json.CollectionFormats$$anon$1$$anonfun$write$1.apply(CollectionFormats.scala:26)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.immutable.List.foreach(List.scala:309)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
    at scala.collection.AbstractTraversable.map(Traversable.scala:105)
    at spray.json.CollectionFormats$$anon$1.write(CollectionFormats.scala:26)
    at spray.json.CollectionFormats$$anon$1.write(CollectionFormats.scala:25)
    at spray.json.PimpedAny.toJson(package.scala:40)
    at spray.json.StandardFormats$OptionFormat.write(StandardFormats.scala:34)
    at spray.json.StandardFormats$OptionFormat.write(StandardFormats.scala:32)
    at spray.json.ProductFormats$class.productElement2Field(ProductFormats.scala:473)
    at spray.json.MyJsonProtocol$.productElement2Field(TestNPE.scala:5)
    at spray.json.ProductFormats$$anon$1.write(ProductFormats.scala:32)
    at spray.json.ProductFormats$$anon$1.write(ProductFormats.scala:30)
    at spray.json.PimpedAny.toJson(package.scala:40)
    at spray.json.TestNPE$.main(TestNPE.scala:18)
    at spray.json.TestNPE.main(TestNPE.scala)

Sooo I tried to fix it myself but my knowledge of Scala is not strong enough yet. NPE happens here when it's attempting to convert inner TestItem. Function parameter write at that moment is null.

Could you please explain to me why it doesn't use my implicit instead ? I see in the debugger that instead of using my implicit write contains value of some magic field evidence$x$y which changes as it goes deeper in calling chain. I don't know what it is. I feel like it's something related to context bound but reading relevant chapter didn't help.


回答1:


Well, I should have been more attentive. I had to use lazyFormat wrapper.



来源:https://stackoverflow.com/questions/16451042/npe-in-spray-json-because-of-recursive-implicits-context-bound-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!