Play + Scala + lift-json serialization fails

75 views
Skip to first unread message

Dirk

unread,
Jan 27, 2011, 3:18:42 PM1/27/11
to play-framework
I've been using lift-json to produce JSON in a scala project. It works fine with primitives and collections, however when I try to serialize a case class there is nothing in the output. I haven't found any related bug reports so I think it may be a problem specific to Play.

Lift Json jars:
http://scala-tools.org/repo-releases/net/liftweb/lift-json_2.8.0/2.2/lift-json_2.8.0-2.2.jar
http://mirrors.ibiblio.org/pub/mirrors/maven2/com/thoughtworks/paranamer/paranamer/2.1/paranamer-2.1.jar

Example (using play scala console):
scala> import net.liftweb.json._
scala> import net.liftweb.json.Serialization._
scala> case class Dog(name: String)
scala> implicit val formats = Serialization.formats(NoTypeHints)
scala> write(Dog("Fido"))
res2: String = {}

Expected output:
{"name": "Fido"}

The relevant code in lift-json:
https://github.com/lift/lift/blob/master/framework/lift-base/lift-json/src/main/scala/net/liftweb/json/Extraction.scala#L51

The same happens whether I run the above code in the play scala console or in a Controller class.
Is there some kind of byte code magic that might cause this not to work in Play?

Dirk

unread,
Mar 1, 2011, 1:50:24 PM3/1/11
to play-framework
I'm following up on an issue I reported earlier whereby lift-json fails to serialize case classes.

It seems that the problem is with the interaction between paranamer and play. Paranamer is a library used by lift-json to get the parameter names for the case class constructor. Play manages its own byte code, so when paranamer attempts to read the class file it fails.

Have a look at this method:
public String[] lookupParameterNames(AccessibleObject methodOrCtor, boolean throwExceptionIfMissing):
http://svn.codehaus.org/paranamer/trunk/paranamer/src/java/com/thoughtworks/paranamer/BytecodeReadingParanamer.java
On line 91 getClassAsStream(declaringClass) attempts to get the class file and fails.

I'm not really sure if there's any way play can get around this problem, but it would be good to get input from play devs as to what changes need to be made so that lift-json can be used by play. Then we can go to the lift-json developers and ask for those changes.

Otherwise there's no easy way to use json with play + scala.
Thanks
Dirk

sledorze

unread,
Mar 2, 2011, 3:57:39 AM3/2/11
to play-framework
Got the same issue, you better work around this in the sort term (no
extract :( ), I think.


On 1 mar, 19:50, Dirk <dirkm...@gmail.com> wrote:
> I'm following up on an issue I reported earlier whereby lift-json fails to
> serialize case classes.
>
> It seems that the problem is with the interaction between paranamer and
> play. Paranamer is a library used by lift-json to get the parameter names
> for the case class constructor. Play manages its own byte code, so when
> paranamer attempts to read the class file it fails.
>
> Have a look at this method:
> public String[] lookupParameterNames(AccessibleObject methodOrCtor, boolean
> throwExceptionIfMissing):http://svn.codehaus.org/paranamer/trunk/paranamer/src/java/com/though...
> On line 91 getClassAsStream(declaringClass) attempts to get the class file
> and fails.
>
> I'm not really sure if there's any way play can get around this problem, but
> it would be good to get input from play devs as to what changes need to be
> made so that lift-json can be used by play. Then we can go to the lift-json
> developers and ask for those changes.
>
> Otherwise there's no easy way to use json with play + scala.
> Thanks
> Dirk
>
>
>
>
>
>
>
> On Thu, Jan 27, 2011 at 5:18 PM, Dirk <dirkm...@gmail.com> wrote:
> > I've been using lift-json to produce JSON in a scala project. It works fine
> > with primitives and collections, however when I try to serialize a case
> > class there is nothing in the output. I haven't found any related bug
> > reports so I think it may be a problem specific to Play.
>
> > Lift Json jars:
>
> >http://scala-tools.org/repo-releases/net/liftweb/lift-json_2.8.0/2.2/...
>
> >http://mirrors.ibiblio.org/pub/mirrors/maven2/com/thoughtworks/parana...
>
> > Example (using play scala console):
> > scala> import net.liftweb.json._
> > scala> import net.liftweb.json.Serialization._
> > scala> case class Dog(name: String)
> > scala> implicit val formats = Serialization.formats(NoTypeHints)
> > scala> write(Dog("Fido"))
> > res2: String = {}
>
> > Expected output:
> > {"name": "Fido"}
>
> > The relevant code in lift-json:
>
> >https://github.com/lift/lift/blob/master/framework/lift-base/lift-jso...

Dirk

unread,
Mar 9, 2011, 1:39:53 PM3/9/11
to play-fr...@googlegroups.com
I posted my question on the lift group and the author of lift-json has made a change so that we can now use lift-json with play:
http://groups.google.com/group/liftweb/browse_thread/thread/b6d5a00605dd9e36

I can make the changes to the scala module so that lift-json becomes the default json encoder instead of gson, however I'd like to receive approval on this issue from play devs first, so that I don't spend time making a change that isn't used.

Guillaume/Sadek, could you please comment?
Thanks,
Dirk

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To post to this group, send email to play-fr...@googlegroups.com.
To unsubscribe from this group, send email to play-framewor...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/play-framework?hl=en.


Guillaume Bort

unread,
Mar 9, 2011, 3:51:48 PM3/9/11
to play-fr...@googlegroups.com
Yes, works for me.

--
Guillaume Bort, http://guillaume.bort.fr

For anything work-related, use g...@zenexity.fr; for everything else,
write guillau...@gmail.com

sledorze

unread,
Mar 9, 2011, 4:57:12 PM3/9/11
to play-framework
Thanks for the investigation,
I am waiting for the upgrade!
Hurry up! :)

On Mar 9, 3:51 pm, Guillaume Bort <guillaume.b...@gmail.com> wrote:
> Yes, works for me.
>
>
>
> On Wed, Mar 9, 2011 at 7:39 PM, Dirk <dirkm...@gmail.com> wrote:
> > I posted my question on the lift group and the author of lift-json has made
> > a change so that we can now use lift-json with play:
> >http://groups.google.com/group/liftweb/browse_thread/thread/b6d5a0060...
>
> > I can make the changes to the scala module so that lift-json becomes the
> > default json encoder instead of gson, however I'd like to receive approval
> > on this issue from play devs first, so that I don't spend time making a
> > change that isn't used.
>
> > Guillaume/Sadek, could you please comment?
> > Thanks,
> > Dirk
>
> Guillaume Bort,http://guillaume.bort.fr
>
> For anything work-related, use g...@zenexity.fr; for everything else,
> write guillaume.b...@gmail.com

Manuel Bernhardt

unread,
Jun 29, 2011, 5:26:30 AM6/29/11
to play-fr...@googlegroups.com
Hi!

I used this method today, by defining

object PlayParameterNameReader extends ParameterNameReader {
def lookupParameterNames(constructor: Constructor[_]) = {
Set(LocalvariablesNamesEnhancer.lookupParameterNames(constructor).toArray(new
Array[String](1)) : _*)
}
}

and then using as formatter

implicit val formats = new DefaultFormats {
override val parameterNameReader = PlayParameterNameReader
}

and finally by serializing with

return Json(write(user))


it's nice and works and all.

Is there any progress on getting this into play-scala so we have it
for free out of the box?

Thanks!

Manuel

Dirk

unread,
Jun 29, 2011, 11:58:12 AM6/29/11
to play-fr...@googlegroups.com
There is an open pull request at
https://github.com/playframework/play-scala/pull/2

Manuel Bernhardt

unread,
Jun 30, 2011, 6:23:34 AM6/30/11
to play-fr...@googlegroups.com
On Wed, Jun 29, 2011 at 5:58 PM, Dirk <dirk...@gmail.com> wrote:
> There is an open pull request at
> https://github.com/playframework/play-scala/pull/2

Neat! Guillaume, Sadek, will we see that one in play-scala soon? Does
seem to be a good fit with the roadmap :)

Reply all
Reply to author
Forward
0 new messages