lift / framework

Lift Framework
http://liftweb.net
Apache License 2.0
1.27k stars 279 forks source link

lift-json extraction fails on Map with algebraic data structure #1077

Closed indrajitr closed 13 years ago

indrajitr commented 13 years ago

relevant topic in mailing list:https://groups.google.com/forum/#!starred/liftweb/ZpcDpNphGMs

I have an algebraic data structure, SingleOrVector. I've made a serializer for it and it works fine if it's not inside a Map, but if I put it inside a map I get an error:

* import net.liftweb.json.Serialization. import net.liftweb.json.

object Test {

class SingleOrVectorSerializer extends Serializer[SingleOrVector[Double]] { private val singleOrVectorClass = classOf[SingleOrVector[Double]]

def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, JValue), SingleOrVector[Double]] = {
  case (TypeInfo(`singleOrVectorClass`, _), json) => json match {
    case JObject( List(JField("val", JDouble(x:Double)) ) ) => SingleValue(x)
    case JObject( List(JField("val", JArray(x:List[JDouble])) ) ) => VectorValue( x.map(_.num).toIndexedSeq )
    case x => throw new MappingException("Can't convert " + x + " to SingleOrVector")
  }
}

def serialize(implicit format: Formats): PartialFunction[Any, JValue] = {
  case SingleValue(x:Double) => JObject( List(JField("val", JDouble(x)) ) )
  case VectorValue(x:Vector[Double]) => JObject( List( JField("val", JArray( x.toList.map(JDouble(_)) ) ) ) )
}

}

implicit val formats = DefaultFormats + new SingleOrVectorSerializer

sealed trait SingleOrVector[A] case class SingleValueA extends SingleOrVector[A] case class VectorValueA extends SingleOrVector[A]

case class A(a:Map[String,SingleOrVector[Double]]) case class B(b:SingleOrVector[Double]) def main(args: Array[String]) {

val jsonString1 =  write( B(SingleValue(2.0)) )
val x = read[B](jsonString1) //this works.
println(x)

val jsonString2 =  write( A(Map("hello"->SingleValue(2.0))) )
val y = read[A](jsonString2) //this fails...
println(y) 

} }

Error:

Exception in thread "main" net.liftweb.json.MappingException: unknown error at net.liftweb.json.Extraction$.extract(Extraction.scala:45) at net.liftweb.json.JsonAST$JValue.extract(JsonAST.scala:290) at net.liftweb.json.Serialization$.read(Serialization.scala:48) at Test$.main(testjsonbug2.scala:48) at Test.main(testjsonbug2.scala) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) Caused by: java.lang.IndexOutOfBoundsException: 0 at scala.collection.LinearSeqOptimized$class.apply(LinearSeqOptimized.scala:51) at scala.collection.immutable.List.apply(List.scala:45) at net.liftweb.json.ScalaSigReader$.findPrimitive$1(ScalaSig.scala:68) at net.liftweb.json.ScalaSigReader$.findArgType(ScalaSig.scala:74) at net.liftweb.json.ScalaSigReader$.readConstructor(ScalaSig.scala:26) at net.liftweb.json.Meta$$anonfun$2.apply(Meta.scala:114) at net.liftweb.json.Meta$$anonfun$2.apply(Meta.scala:112) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:194) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:194) at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59) at scala.collection.immutable.List.foreach(List.scala:45) at scala.collection.TraversableLike$class.map(TraversableLike.scala:194) at scala.collection.immutable.List.map(List.scala:45) at net.liftweb.json.Meta$.parameterizedTypeOpt$1(Meta.scala:112) at net.liftweb.json.Meta$.mkConstructor$1(Meta.scala:123) at net.liftweb.json.Meta$.fieldMapping$1(Meta.scala:139) at net.liftweb.json.Meta$.mkContainer$1(Meta.scala:106) at net.liftweb.json.Meta$.fieldMapping$1(Meta.scala:135) at net.liftweb.json.Meta$.toArg$1(Meta.scala:153) at net.liftweb.json.Meta$$anonfun$constructors$1$1$$anonfun$apply$1.apply(Meta.scala:98) at net.liftweb.json.Meta$$anonfun$constructors$1$1$$anonfun$apply$1.apply(Meta.scala:97) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:194) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:194) at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59) at scala.collection.immutable.List.foreach(List.scala:45) at scala.collection.TraversableLike$class.map(TraversableLike.scala:194) at scala.collection.immutable.List.map(List.scala:45) at net.liftweb.json.Meta$$anonfun$constructors$1$1.apply(Meta.scala:97) at net.liftweb.json.Meta$$anonfun$constructors$1$1.apply(Meta.scala:96) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:194) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:194) at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59) at scala.collection.immutable.List.foreach(List.scala:45) at scala.collection.TraversableLike$class.map(TraversableLike.scala:194) at scala.collection.immutable.List.map(List.scala:45) at net.liftweb.json.Meta$.constructors$1(Meta.scala:96) at net.liftweb.json.Meta$$anonfun$mappingOf$1.apply(Meta.scala:164) at net.liftweb.json.Meta$$anonfun$mappingOf$1.apply(Meta.scala:159) at net.liftweb.json.Meta$Memo.memoize(Meta.scala:198) at net.liftweb.json.Meta$.mappingOf(Meta.scala:159) at net.liftweb.json.Extraction$.mkMapping$1(Extraction.scala:192) at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$extract0(Extraction.scala:194) at net.liftweb.json.Extraction$.extract(Extraction.scala:42) ... 9 more

Process finished with exit code 1

github-importer commented 12 years ago

Imported from Assembla: http://www.assembla.com/spaces/liftweb/tickets/1077