pickling
pickling copied to clipboard
v 0.9.1 unpickle[Any] works for array but not for list
in v 0.9.1
the following works:
test("non-primitive array") {
def testIt(x: Any): Unit = {
val p = x.pickle
val up = p.unpickle[Any]
val arr = up.asInstanceOf[Array[(Int, Double)]]
assert(arr.mkString(",") == "(5,0.5),(6,0.6)")
}
val arr: Array[(Int, Double)] =
Array(5 -> 0.5d, 6 -> 0.6d)
testIt(arr)
}
yet this fails:
test("non-primitive list") {
def testIt(x: Any): Unit = {
val p = x.pickle
val up = p.unpickle[Any]
val arr = up.asInstanceOf[List[(Int, Double)]]
assert(arr.mkString(",") == "(5,0.5),(6,0.6)")
}
val list: List[(Int, Double)] =
List(5 -> 0.5d, 6 -> 0.6d)
testIt(list)
}
with error:
scala.ScalaReflectionException: Scala field hd isn't represented as a Java field, neither it has a Java accessor method
note that private parameters of class constructors don't get mapped onto fields and/or accessors,
unless they are used outside of their declaring constructors.
at scala.reflect.runtime.JavaMirrors$JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$ErrorNonExistentField(JavaMirrors.scala:132)
what am I missing?
Using Pickling 0.10.0, I get opposite result on REPL:
scala> import scala.pickling.Defaults._
import scala.pickling.Defaults._
scala> import scala.pickling.json._
import scala.pickling.json._
scala> Array(5 -> 0.5d, 6 -> 0.6d).pickle
res0: pickling.json.pickleFormat.PickleType =
JSONPickle({
"$type": "scala.Array[scala.Tuple2[scala.Int,scala.Double]]",
"elems": [
{
"$type": "scala.Tuple2[scala.Int,scala.Double]",
"_1": 5,
"_2": 0.5
},
{
"$type": "scala.Tuple2[scala.Int,scala.Double]",
"_1": 6,
"_2": 0.6
}
]
})
scala> res0.unpickle[Any]
java.lang.ClassNotFoundException: scala/Tuple2[scala/Int,scala/Double]
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:190)
at scala.pickling.internal.Classes$.classTagFromString(Classes.scala:16)
at scala.pickling.internal.Classes$.classFromString(Classes.scala:23)
at scala.pickling.runtime.RuntimeUnpicklerLookup$.genUnpickler(RuntimeUnpicklerLookup.scala:22)
at scala.pickling.pickler.AnyUnpicklers$$anon$1.unpickle(Any.scala:12)
at scala.pickling.Unpickler$class.unpickleEntry(Pickler.scala:79)
at scala.pickling.pickler.AnyUnpicklers$$anon$1.unpickleEntry(Any.scala:10)
at scala.pickling.functions$.unpickle(functions.scala:11)
at scala.pickling.UnpickleOps.unpickle(Ops.scala:23)
... 43 elided
scala> List(5 -> 0.5d, 6 -> 0.6d).pickle
warning: there was one deprecation warning; re-run with -deprecation for details
res3: pickling.json.pickleFormat.PickleType =
JSONPickle({
"$type": "scala.collection.immutable.$colon$colon[scala.Tuple2[scala.Int,scala.Double]]",
"head": {
"_1": 5,
"_2": 0.5
},
"tl": {
"$type": "scala.collection.immutable.$colon$colon[scala.Tuple2[scala.Int,scala.Double]]",
"head": {
"_1": 6,
"_2": 0.6
},
"tl": {
"$type": "scala.collection.immutable.Nil.type"
}
}
})
scala> res3.unpickle[Any]
res4: Any = List((5,0.5), (6,0.6))
I am having the issue with 0.10.1 on Scala 2.10.6.
Surely serialising a Scala list shouldn't cause issues.
@baank Give a try to the last milestone release of 0.11.0-M2. It's solved this problem and I'm pretty certain you won't have any more problems at all. However, beware that we have changed some internal APIs. If you are using scala pickling for only basic pickling/unpickling, you won't have any problem.
@jvican, it seems @baank is on Scala 2.10. So far, pickling 0.11.x isn't cross-compiled for both 2.11 and 2.10.
Can it be?
Hey! Yes, Scala pickling is compiling in 2.10, the only thing missing is to publish an artifact for that version. :smile:
Ok, thanks for letting me know! I'll see if I can tag and cut a release for 0.11.0-M2 on 2.10 :) Will let you know when it's propagated... Hopefully this fixes @baank's issues.
Yes, let's hope it fixes them!
Note, though, that we recommend the use of static picklers and unpicklers over AnyPicklerUnpickler. I don't know the details of your particular use case, but it's always better to specify the type unless you're forced to use Any. I'll try to update the release notes so that first users of the new release know all the changes and have a basic tutorial.