NPE в spray-json из-за рекурсивных имплицитов (проблема с привязкой к контексту?)

Возможно, я обнаружил ошибку в spray-json. Я получаю исключение Null Pointer Exception, когда пытаюсь получить json объекта, который имеет поле типа самого себя. Пример:

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)
  }
}

И стек вызовов это

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)

Оооо, я пытался исправить это сам, но мои знания Scala еще недостаточно сильны. NPE происходит здесь при попытке преобразовать внутренний TestItem. Параметр функции write в этот момент равен null.

Не могли бы вы объяснить мне, почему вместо этого не используется мой имплицит? Я вижу в отладчике, что вместо использования моего неявного write содержит значение некоторого магического поля evidence$x$y, которое изменяется по мере его углубления в цепочка вызовов. Я не знаю, что это такое. Я чувствую, что это связано с контекстом, но чтение соответствующая глава не помогло.


person expert    schedule 08.05.2013    source источник


Ответы (1)


Ну, я должен был быть более внимательным. Мне пришлось использовать обертку lazyFormat.

person expert    schedule 08.05.2013