jsonscalaplayframework-2.2play-jsonplayframework-json

json writer for nested classes


I'm using Play! Scala 2.2 and I have a problem to render a class in Json :

I have two classes with one depending of the other, as following :

case class Artist(id: String, cover: String, website: List[String], link: String, Tracks: List[Track] = List())

case class Track(stream_url: String, title: String, artwork_url: Option[String] )

And their implicit Writers :

implicit val artistWrites: Writes[Artist] = Json.writes[Artist]

implicit val trackWrites: Writes[Track] = Json.writes[Track]

The writers work well as following :

println(Json.toJson(Track("aaa", "aaa", Some("aaa"))))
println(Json.toJson(Artist("aaa", "aaa", List("aaa"), "aaa", List())))

i.e if the Artist have an empty list of tracks. But if I want to do this :

println(Json.toJson(Artist("aaa", "aaa", List("aaa"), "aaa", List(SoundCloudTrack("ljkjk", "ljklkj", Some("lkjljk"))))))

I get an execution exception : [NullPointerException: null]

Can you please explain me what I am doing wrong?


Solution

  • The problem is the initialization order. Json.writes[Artist] requires an implicit Writes[Track] in order to generate itself. The compiler is able to find the implicit Writes[Track], because you're declaring it in the same object, however trackWrites is initialized after artistWrites, which means that when Json.writes[Artist] is called, trackWrites is null. This doesn't interrupt the creation of artistWrites, however, so it goes unnoticed until it's actually used.

    You can fix this by simply switching the initialization order, so that trackWrites is first.