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?
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.