Jeremy
Jeremy

Reputation: 205

Serializing and unserializing case classes with lift-json

I'm attempting basic serialization/hydration with lift-json, but without success. As near as I can tell from the package readme, this should work. Help?

I'm using Scala 2.8.0 and Lift 2.2 cross-built for 2.8 with sbt ("net.liftweb" %% "lift-json" % "2.2").

import net.liftweb.json._
import net.liftweb.json.Serialization.{read, write}

implicit val formats = Serialization.formats(NoTypeHints)

case class Route(title: String)

val rt = new Route("x277a1")

val ser = write(rt)
// ser: String = {} ... 

val deser = read[Route]("""{"title":"Some Title"}""")
// net.liftweb.json.MappingException: Parsed JSON values do not match with class constructor

Upvotes: 8

Views: 3544

Answers (2)

v6ak
v6ak

Reputation: 1656

The same problem applies every time when the (de)serialuzed class is not on the classpath. In such case, paranamer can't read the parameter names. It is necessary to provide a custom ParameterNameReader.

Such problem applies for e.g.:

  • REPL (as mentioned) - unless you define the class outside the REPL and add via classpath.
  • Play Framework - unless you provide a simple custom ParameterNameReader (see below) or load the (de)serialized class as a Maven/Play/... dependency
  • Feel free to add another situation (you can edit this post).

The PlayParameterNameReader:

import net.liftweb.json.ParameterNameReader
import java.lang.reflect.Constructor
import play.classloading.enhancers.LocalvariablesNamesEnhancer
import scala.collection.JavaConversions._

object PlayParameterReader extends ParameterNameReader{
    def lookupParameterNames(constructor: Constructor[_]) = LocalvariablesNamesEnhancer.lookupParameterNames(constructor)
}

Upvotes: 2

Joni
Joni

Reputation: 2789

Lift JSON's serialization does not work for case classes defined in REPL (paranamer can't find the bytecode to read the type metadata). Compile Route with scalac and then the above example works.

Upvotes: 10

Related Questions