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:
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
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]]
}
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]) {
} }
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