playframework / play-json

The Play JSON library
Apache License 2.0
361 stars 134 forks source link

NPE when Json.toJson #100

Open He-Pin opened 7 years ago

He-Pin commented 7 years ago
Caused by: java.lang.NullPointerException
    at play.api.libs.json.LowPriorityWrites.$anonfun$traversableWrites$2(Writes.scala:307)
    at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:234)
    at scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:59)
    at scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:52)
    at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48)
    at scala.collection.TraversableLike.map(TraversableLike.scala:234)
    at scala.collection.TraversableLike.map$(TraversableLike.scala:227)
    at scala.collection.AbstractTraversable.map(Traversable.scala:104)
    at play.api.libs.json.LowPriorityWrites.$anonfun$traversableWrites$1(Writes.scala:307)
    at play.api.libs.json.Writes$$anon$6.writes(Writes.scala:142)
    at play.api.libs.json.PathWrites.$anonfun$nullable$2(JsConstraints.scala:184)
    at play.api.libs.json.OWrites$$anon$3.writes(Writes.scala:111)
    at play.api.libs.json.OWrites$MergedOWrites$.mergeIn(Writes.scala:75)
    at play.api.libs.json.OWrites$MergedOWrites$$anon$1.writeFields(Writes.scala:67)
    at play.api.libs.json.OWrites$MergedOWrites$$anon$1.writeFields(Writes.scala:63)
    at play.api.libs.json.OWrites$MergedOWrites$.mergeIn(Writes.scala:73)
    at play.api.libs.json.OWrites$MergedOWrites$$anon$1.writeFields(Writes.scala:66)
    at play.api.libs.json.OWrites$MergedOWrites$$anon$1.writeFields(Writes.scala:63)
    at play.api.libs.json.OWrites$OWritesFromFields.writes(Writes.scala:95)
    at play.api.libs.json.OWrites$OWritesFromFields.writes$(Writes.scala:93)
    at play.api.libs.json.OWrites$MergedOWrites$$anon$1.writes(Writes.scala:63)
    at play.api.libs.json.OWrites$$anon$2.$anonfun$contramap$1(Writes.scala:106)
    at play.api.libs.json.OWrites$$anon$3.writes(Writes.scala:111)
    at play.api.libs.json.OWrites$$anon$3.writes(Writes.scala:110)
    at play.api.libs.json.LowPriorityWrites.$anonfun$traversableWrites$2(Writes.scala:307)
    at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:234)
    at scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:59)
    at scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:52)
    at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48)
    at scala.collection.TraversableLike.map(TraversableLike.scala:234)
    at scala.collection.TraversableLike.map$(TraversableLike.scala:227)
    at scala.collection.AbstractTraversable.map(Traversable.scala:104)
    at play.api.libs.json.LowPriorityWrites.$anonfun$traversableWrites$1(Writes.scala:307)
    at play.api.libs.json.Writes$$anon$6.writes(Writes.scala:142)
    at play.api.libs.json.Json$.toJson(Json.scala:186)
    at controllers.FacadesController.$anonfun$queryTypes$2(FacadesController.scala:28)
He-Pin commented 7 years ago

image

He-Pin commented 7 years ago

The root cause is I am using a Recursive Types and auto mapping, so boom! The automapping gave me a Writes, but with the recursived one as null.

He-Pin commented 7 years ago

easy fixed with a lazy.

  1. The macro should throw exception when auto mapping the recursive type.
  2. When the Writes is null,throw an exception.
  3. Yes,two lazy vals will give a SOF, eg:
    java.lang.StackOverflowError
    at scala.collection.SeqLike.$colon$plus$(SeqLike.scala:559)
    at scala.collection.AbstractSeq.$colon$plus(Seq.scala:41)
    at play.api.libs.json.JsPath.$bslash(JsPath.scala:186)
    at services.schema.FieldDescription$.writes$lzycompute(SchemaManager.scala:234)
    at services.schema.FieldDescription$.writes(SchemaManager.scala:234)
    at services.schema.TypeDescription$.writes$lzycompute(SchemaManager.scala:198)
    at services.schema.TypeDescription$.writes(SchemaManager.scala:198)
cchantep commented 7 years ago

Hi @hepin1989, the macro could check for direct reference to the same type (which anyway lead to issue in Scala), on the other side indirect reference using Option or Traversable could be supported.