No JSon serializer found for Class. Try to implement an implicit Writes or Format for this type.

1,079 views
Skip to first unread message

Akash Agarwal

unread,
May 20, 2015, 6:08:38 PM5/20/15
to play-fr...@googlegroups.com
My case class looks like 

case class Notification(
startTime: DateTime
endTime: DateTime,
bunch of other stuff
)

I have given the formatter as - 

object json { 
private lazy val ISODateTimeFormatter = ISODateTimeFormat.dateTime.withZone(DateTimeZone.forID("America/Los_Angeles"))
  private lazy val ISODateTimeParser = ISODateTimeFormat.dateTimeParser

  implicit val DateTimeFormatter = new Format[DateTime] {
    def reads(j: JsValue) = JsSuccess(ISODateTimeParser.parseDateTime(j.as[String]))
    def writes(o: DateTime): JsValue = JsString(ISODateTimeFormatter.print(o))
  }
implicit val notification = format[Notification]
}

and I am trying to use this class in a integration test case by import json._ and still getting the serializer error. Does anyone know what might be going on here.

Thanks,
AKah

Michael Slinn

unread,
May 21, 2015, 4:38:37 PM5/21/15
to play-fr...@googlegroups.com
It used to be possible to write the following, once all the Reads and Writes were in scope:

private implicit val notificationFormatter = Json.format[Notification]

That nicely succinct shorthand no longer works. It would be terrific if something like this was still possible.

Marius Soutier

unread,
May 25, 2015, 5:04:26 AM5/25/15
to play-fr...@googlegroups.com
I’ve seen the case where you had to be explicit in the type annotation. I’d receive the same compilation error and could only fix it by adding the explicit type:

implicit val notification: Format[Notification] = Json.format[Notification]

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Michael Slinn

unread,
May 25, 2015, 2:08:23 PM5/25/15
to play-fr...@googlegroups.com
Marius,

Following your advice, I get:

No unapply or unapplySeq function found

This used to work!

Thank you,

Mike

Marius Soutier

unread,
May 25, 2015, 2:59:33 PM5/25/15
to play-fr...@googlegroups.com
Works for me (as of 2.3). Can you share a little more code?

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.

Mike Slinn

unread,
May 25, 2015, 3:03:46 PM5/25/15
to play-fr...@googlegroups.com
Marius,

Play-JSON v2.4 seems to have changed its behavior from 2.3; this inquiry
is specific to Play 2.4.

def jsonDate2 = Action { implicit request =>
case class Notification(
startTime: DateTime,
endTime: DateTime
)

val ISODateTimeFormatter: DateTimeFormatter =
ISODateTimeFormat.dateTime.withZone(DateTimeZone.forID("America/Los_Angeles"))
val ISODateTimeParser: DateTimeFormatter =
ISODateTimeFormat.dateTimeParser

implicit val dateTimeFormatter = new Format[DateTime] {
def reads(j: JsValue) =
JsSuccess(ISODateTimeParser.parseDateTime(j.as[String]))
def writes(o: DateTime): JsValue =
JsString(ISODateTimeFormatter.print(o))
}
implicit val notification: Format[Notification] =
Json.format[Notification]// boom!

val startTime =
ISODateTimeFormat.dateTime().parseDateTime("2014-07-12T18:31:01.000Z")
val endTime =
ISODateTimeFormat.dateTime().parseDateTime("2015-07-12T18:31:01.000Z")
val jsonNotification: JsValue = Json.toJson(Notification(startTime,
endTime))
val notification = jsonNotification.as[Notification]// boom!
Ok
}

Thank you,

Mike

Marius Soutier

unread,
May 25, 2015, 3:26:10 PM5/25/15
to play-fr...@googlegroups.com
Just move the case class outside the action.
> --
> You received this message because you are subscribed to the Google Groups "play-framework" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/55637205.8000201%40gmail.com.

Mike Slinn

unread,
May 25, 2015, 3:30:11 PM5/25/15
to play-fr...@googlegroups.com
You are most correct, monsieur. But why does this work?

Thanks,

Mike

Marius Soutier

unread,
May 25, 2015, 3:34:05 PM5/25/15
to play-fr...@googlegroups.com
I guess the macro can’t generate a static reference to a class that gets defined each time the method is called.
> --
> You received this message because you are subscribed to the Google Groups "play-framework" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/55637835.80502%40gmail.com.

Mike Slinn

unread,
May 25, 2015, 3:35:34 PM5/25/15
to play-fr...@googlegroups.com
Sounds reasonable :)

Marius Soutier

unread,
May 25, 2015, 3:43:52 PM5/25/15
to play-fr...@googlegroups.com
Yeah ;)

Cheers
- Marius

> On 25.05.2015, at 21:35, Mike Slinn <msl...@gmail.com> wrote:
>
> Sounds reasonable :)
>
> --
> You received this message because you are subscribed to the Google Groups "play-framework" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/5563797D.5020805%40gmail.com.

James Roper

unread,
May 26, 2015, 3:37:13 AM5/26/15
to play-framework
The macro was refactored quite a bit to simplify in Play 2.4 - I don't know if that's broken things or not.

But case classes defined inside functions is probably not a good idea in general, some weird things happen, like:

scala> def foo = { case class Bar(a: String); Bar }
<console>:7: warning: inferred existential type Bar.type forSome { val Bar: scala.runtime.AbstractFunction1[String,Bar] with Serializable{case def unapply(x$0: Bar): Option[String]}; type Bar <: Product with Serializable{val a: String; def copy(a: String): Bar; def copy$default$1: String @scala.annotation.unchecked.uncheckedVariance} }, which cannot be expressed by wildcards,  should be enabled
by making the implicit value scala.language.existentials visible.
This can be achieved by adding the import clause 'import scala.language.existentials'
or by setting the compiler option -language:existentials.
See the Scala docs for value scala.language.existentials for a discussion
why the feature should be explicitly enabled.
       def foo = { case class Bar(a: String); Bar }
                 ^
<console>:5: error: type mismatch;
 found   : Bar.type(in lazy value $result) where type Bar.type(in lazy value $result) <: scala.runtime.AbstractFunction1[String,Bar] with Serializable{case def unapply(x$0: Bar): Option[String]} with Singleton
 required: (some other)Bar.type(in lazy value $result) forSome { type (some other)Bar.type(in lazy value $result) <: scala.runtime.AbstractFunction1[String,Bar] with Serializable{case def unapply(x$0: Bar): Option[String]} with Singleton; type Bar <: Product with Serializable{val a: String; def copy(a: String): Bar; def copy$default$1: String} }
  lazy val $result = foo
                                          ^
<console>:5: error: type mismatch;
 found   : Bar.type(in value $result) where type Bar.type(in value $result) <: scala.runtime.AbstractFunction1[String,Bar] with Serializable{case def unapply(x$0: Bar): Option[String]} with Singleton
 required: Bar.type(in lazy value $result) forSome { type Bar.type(in lazy value $result) <: scala.runtime.AbstractFunction1[String,Bar] with Serializable{case def unapply(x$0: Bar): Option[String]} with Singleton; type Bar <: Product with Serializable{val a: String; def copy(a: String): Bar; def copy$default$1: String} }
  lazy val $result = foo




For more options, visit https://groups.google.com/d/optout.



--
James Roper
Software Engineer

Typesafe – Build reactive apps!
Twitter: @jroper

Naftoli Gugenheim

unread,
May 27, 2015, 1:53:48 PM5/27/15
to play-framework

FWIW I believe upickle (another macro-based json de/serializer) has the same limitation.


Reply all
Reply to author
Forward
0 new messages