-
-
Notifications
You must be signed in to change notification settings - Fork 134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NullPointerException trying to pickle Coursier case class #120
Comments
FWIW this seems to work fine implicit val depFormat: Format[coursier.Dependency] = new Format[coursier.Dependency] {
def writes(o: Dependency) = {
Json.obj(
"module" -> Json.toJson(o.module),
"version" -> Json.toJson(o.version),
"configuration" -> Json.toJson(o.configuration),
"exclusions" -> Json.toJson(o.exclusions),
"attributes" -> Json.toJson(o.attributes),
"optional" -> Json.toJson(o.optional),
"transitive" -> Json.toJson(o.transitive)
)
}
def reads(json: JsValue) = json match{
case x: JsObject =>
JsSuccess(coursier.Dependency(
Json.fromJson[coursier.Module](x.value("module")).get,
Json.fromJson[String](x.value("version")).get,
Json.fromJson[String](x.value("configuration")).get,
Json.fromJson[coursier.Attributes](x.value("attributes")).get,
Json.fromJson[Set[(String, String)]](x.value("exclusions")).get,
Json.fromJson[Boolean](x.value("optional")).get,
Json.fromJson[Boolean](x.value("transitive")).get
))
case _ => JsError("Dep must be an object")
}
} |
Hi, thanks for reporting. Please note that the following codes are working: {
implicit val modFormat: Format[coursier.Module] = Json.format
implicit val attrFormat: Format[coursier.Attributes] = Json.format
implicit val depFormat: Format[coursier.Dependency] = Json.format
Json.toJson(coursier.Dependency(coursier.Module("org.scala-lang", "scala-reflect"), "2.12.4"))
}
{
implicit val modFormat: Format[coursier.Module] = Json.format
implicit val depFormat: Format[coursier.Dependency] = Json.format
implicit lazy val attrFormat: Format[coursier.Attributes] = Json.format
Json.toJson(coursier.Dependency(coursier.Module("org.scala-lang", "scala-reflect"), "2.12.4"))
}
From there I would say that the issue, not specific to Play JSON, is a forward declaration of implicit instances. Best regards. |
We had a similar issue (pasting stack because it points to a different line)
The case class Would it be possible to detect this case in the macro and throw a compile-time exception? |
@francisdb not sure it's possible. Btw the same kind of NPE is raise for |
A simple null check on the reads after implicit resolution could throw an exception indicating that this forward declaration might be the cause? Anything is better than a NullpointerException deep in the play-json code. |
Unfortunately, it doesn't seem possible for a macro to check the actual position of an resolved implicit instance. On the other side, as such forward reference raises a compilation warning as bellow, it can be handled (or blocked by making the warning fatal).
|
@cchantep Thanks, it seems you are right that the initialization order is the problem. Perhaps one mitigation would be to change the examples in the readme to use Also, while it may be unavoidable to throw a NPE, I wonder if it is possible to tweak the macro to throw an NPE as early as possible? Ideally I'd like the NPE to be thrown when defining the |
It still exists in version 2.9.0. It is really annoying, since it is a runtime error + there is absolutely no sign where the problem is or what type is missing the required Writes... |
The text was updated successfully, but these errors were encountered: