-
-
Notifications
You must be signed in to change notification settings - Fork 841
Description
Describe the bug
Kryo5 cannot serialize the following scala case class which has one variable length argument:
case class TestVarArgs(vargs: String*)
It works with Kryo4 (4.0.2). Seems like this is a regression issue in Kryo5.
Error message:
[warn] either append it to `Global / excludeLintKeys` or call .withRank(KeyRanks.Invisible) on the key
[info] running com.roczei.testing.Main
[error] com.esotericsoftware.kryo.kryo5.KryoException: java.lang.ClassCastException: class [Ljava.lang.String; cannot be cast to class java.lang.String ([Ljava.lang.String; and java.lang.String are in module java.base of loader 'bootstrap'
[error] Serialization trace:
[error] array (scala.collection.mutable.WrappedArray$ofRef)
[error] vargs (com.roczei.testing.TestVarArgs)
[error] at com.esotericsoftware.kryo.kryo5.serializers.ReflectField.write(ReflectField.java:101)
[error] at com.esotericsoftware.kryo.kryo5.serializers.FieldSerializer.write(FieldSerializer.java:108)
[error] at com.esotericsoftware.kryo.kryo5.Kryo.writeObject(Kryo.java:642)
[error] at com.esotericsoftware.kryo.kryo5.serializers.ReflectField.write(ReflectField.java:70)
[error] at com.esotericsoftware.kryo.kryo5.serializers.FieldSerializer.write(FieldSerializer.java:108)
[error] at com.esotericsoftware.kryo.kryo5.Kryo.writeObject(Kryo.java:627)
[error] at com.roczei.testing.Main$.main(Main.scala:21)
[error] at com.roczei.testing.Main.main(Main.scala)
[error] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[error] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[error] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error] at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[error] Caused by: java.lang.ClassCastException: class [Ljava.lang.String; cannot be cast to class java.lang.String ([Ljava.lang.String; and java.lang.String are in module java.base of loader 'bootstrap')
[error] at com.esotericsoftware.kryo.kryo5.serializers.DefaultSerializers$StringSerializer.write(DefaultSerializers.java:164)
[error] at com.esotericsoftware.kryo.kryo5.Kryo.writeObjectOrNull(Kryo.java:692)
[error] at com.esotericsoftware.kryo.kryo5.serializers.ReflectField.write(ReflectField.java:79)
[error] at com.esotericsoftware.kryo.kryo5.serializers.FieldSerializer.write(FieldSerializer.java:108)
[error] at com.esotericsoftware.kryo.kryo5.Kryo.writeObject(Kryo.java:642)
[error] at com.esotericsoftware.kryo.kryo5.serializers.ReflectField.write(ReflectField.java:70)
[error] at com.esotericsoftware.kryo.kryo5.serializers.FieldSerializer.write(FieldSerializer.java:108)
[error] at com.esotericsoftware.kryo.kryo5.Kryo.writeObject(Kryo.java:627)
[error] at com.roczei.testing.Main$.main(Main.scala:21)
[error] at com.roczei.testing.Main.main(Main.scala)
[error] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[error] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[error] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error] at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[error] stack trace is suppressed; run last Compile / run for the full output
[error] (Compile / run) com.esotericsoftware.kryo.kryo5.KryoException: java.lang.ClassCastException: class [Ljava.lang.String; cannot be cast to class java.lang.String ([Ljava.lang.String; and java.lang.String are in module java.base of loader 'bootstrap')
[error] Serialization trace:
[error] array (scala.collection.mutable.WrappedArray$ofRef)
[error] vargs (com.roczei.testing.TestVarArgs)
[error] Total time: 1 s, completed 18 Apr 2023, 19:23:51
Other test results:
https://github.com/roczei/kryo_repro/blob/main/repro-logs-kryo5-bad.txt
To Reproduce
Example scala code:
import com.esotericsoftware.kryo.kryo5.Kryo
import com.esotericsoftware.kryo.kryo5.io.Input
import com.esotericsoftware.kryo.kryo5.io.Output
import com.esotericsoftware.kryo.kryo5.objenesis.strategy.StdInstantiatorStrategy
import java.io.{FileInputStream, FileOutputStream}
case class TestVarArgs(vargs: String*)
object Main {
def main(args: Array[String]): Unit = {
val kryo = new Kryo()
kryo.setInstantiatorStrategy(new StdInstantiatorStrategy())
kryo.register(classOf[TestVarArgs])
kryo.register(Class.forName("scala.collection.immutable.ArraySeq$ofRef"))
kryo.register(Class.forName("[Ljava.lang.String;"))
val t = TestVarArgs("hey", "you", "guys")
val output = new Output(new FileOutputStream("file.bin"))
kryo.writeObject(output, t)
output.close()
val input = new Input(new FileInputStream("file.bin"))
val i = kryo.readObject(input, classOf[TestVarArgs])
input.close()
assert(i.equals(t))
}
}
Bad results (Kryo5):
git clone git@github.com:roczei/kryo_repro.git
cd scala_project_kryo5-2.13.8
sbt run
or
cd scala_project_kryo5-2.12.7
sbt run
or
cd scala_project_kryo5-2.11.12
sbt run
Console outputs: https://github.com/roczei/kryo_repro/blob/main/repro-logs-kryo5-bad.txt
Good result (Kryo4)
cd scala_project_kryo4-2.13.8
sbt run
Console output:
https://github.com/roczei/kryo_repro/blob/main/kryo4-good-logs.txt
OS: macosx but I think this is not OS related
JDK: Azul Systems, Inc. Java 11.0.16 / Azul Systems, Inc. Java 1.8.0_345 (probably it can be reproduced with other jave versions as well)
Scala versions: 2.11.12, 2.12.7, 2.13.8
Kryo Version: all Kryo5 versions
Additional context
I would like to finish this pull request what nicknezis has started (update chill to the newer Kryo 5): twitter/chill#514 and currently this is blocking me to finish this task (latest pull request): roczei/chill#1. Similar issue was mentioned in this kryo thread as well: