2015-02-20 2 views
5

Ich benutze Play! Scala 2.2 und ich habe ein Problem, ein class in Json zu machen:Scala: json writer für verschachtelte Klassen spielen

Ich habe zwei Klassen mit einem der anderen abhängig, wie folgend:

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

Und ihrem impliziten Writers:

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

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

Die Schreiber funktionieren gut wie folgt:

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

, d. H. Wenn die Artist eine leerelist of tracks haben. Aber wenn ich dies tun wollen:

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

ich ein execution exception: [NullPointerException: null]

Können Sie mir bitte erklären, was ich falsch mache? Danke;)

Antwort

4

Das Problem ist die Reihenfolge der Initialisierung. Json.writes[Artist] benötigt eine implizite Writes[Track] um sich selbst zu generieren. Der Compiler ist in der Lage die implizite Writes[Track] zu finden, weil Sie es in demselben Objekt sind erklärt, jedochtrackWrites wird initialisiert nachartistWrites, was bedeutet, dass, wenn Json.writes[Artist] genannt wird, trackWritesnull ist. Dies unterbricht jedoch nicht die Erzeugung von artistWrites, so dass es unbemerkt bleibt, bis es tatsächlich verwendet wird.

Sie können dies beheben, indem Sie einfach die Reihenfolge der Initialisierung ändern, so dass trackWrites zuerst ist.

+0

Ich wusste das nicht! Danke;) – Simon

+0

Es ist leicht, in diese Falle zu geraten, weil der Compiler keine Warnungen darüber abgibt. Vermutlich 99% der NPEs, die ich in Scala bekomme, treten bei Problemen mit der Initialisierungsreihenfolge auf. –