CanBuildFrom/GenTraversableFactory causing serialization issue
I can reproduce with the following code on scala 2.12.
import java.io.{ByteArrayOutputStream, ObjectOutputStream}
import org.scalacheck._
object SerDe {
def main(args: Array[String]): Unit = {
val oos = new ObjectOutputStream(new ByteArrayOutputStream)
val arbInt = implicitly[Arbitrary[Int]]
oos.writeObject(arbInt)
val arbList = implicitly[Arbitrary[List[Int]]]
oos.writeObject(arbList)
}
}
Looks like it's summoning the following implicit in BuildableVersionSpecific.
implicit def buildableCanBuildFrom[T,F,C](implicit c: CanBuildFrom[F,T,C]): Buildable[T,C]
And I can see one for list in SerializableCanBuildFroms
implicit def listCanBuildFrom[T]: CanBuildFrom[List[T], T, List[T]]
But somehow it's not summoned.
Stack trace:
[error] (run-main-2) java.io.NotSerializableException: scala.collection.generic.GenTraversableFactory$$anon$1
[error] java.io.NotSerializableException: scala.collection.generic.GenTraversableFactory$$anon$1
[error] at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
[error] at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
[error] at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
[error] at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
[error] at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) scalacheck / Test / runMain 0s
[error] at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1378)
[error] at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
[error] at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
[error] at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
[error] at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
[error] at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
[error] at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
[error] at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
[error] at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
[error] at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
[error] at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
[error] at magnolia.scalacheck.test.SerDe$.main(SerDe.scala:15)
[error] at magnolia.scalacheck.test.SerDe.main(SerDe.scala)
[error] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[error] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[error] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error] at java.lang.reflect.Method.invoke(Method.java:498)
Adding import org.scalacheck.util.SerializableCanBuildFroms._ fixes the issue. Is it by design that they're not in scope?
There's a serializability test in ScalaCheck that works. Ironically, the import you needed was removed from that test in d8f1322. I know forking the JVM was needed for the test to work in Scala 2.13, but you're asking about 2.12, so I'm not sure why you need the import.
That test you linked doesn't cover Arbitrary[List[T]] though, which summons CanBuildFrom transitively. So it was probably an unused import. Forking for 2.13 might be a different issue since CanBuildFrom was replaced with Factory which is serializable.
So it does look like these implicits need to be manually imported.
Yes, a test of Arbitrary[List[T]] is missing. Good catch. For that test, it would require that import statement.