问题
Situation
I'm serializing an implementation of this class:
abstract class FnDescriptor[T <: FnRequest: TypeTag, R <: FnResponse: TypeTag] with Serializable {
override type Input = T
override type Output = R
override type State = S
val inputTag: TypeTag[Input] = implicitly[TypeTag[T]]
val outputTag: TypeTag[Output] = implicitly[TypeTag[R]]
}
and sending it over REST to a Gateway, which reads it to find the types of input and output state. (Yes I know this isn't a great design)
Results
Now if I run a test, launching both the gateway and the requester who serializes the FnNamespace everything goes fine.
If however I launch the executables separately, that is the gateway in an executable and the requester in another, I get the following error:
java.lang.ClassCastException: cannot assign instance of scala.reflect.api.SerializedTypeTag to field com.package.structure.FnDescriptor.inputTag of type scala.reflect.api.TypeTags$TypeTag in instance of com.package.structure.FnDescriptor$$anon$1
Clues
The research I've done says that the Serializer transformed the TypeTag to a SerializedTypeTag using the writeReplace method. A corresponding readResolve should happen at the deserializer to transform the SerializedTypeTag back to a TypeTag, but it does not happen. Instead it tries to assign a SerializedTypeTag to a TypeTag causing the exception.
The fact that it doesn't happen in a single JVM is the best clue I have, though I don't know how to interpret it.
Full stacktrace
java.lang.ClassCastException: cannot assign instance of scala.reflect.api.SerializedTypeTag to field com.package.structure.FnDescriptor.inputTag of type scala.reflect.api.TypeTags$TypeTag in instance of com.package.structure.FnDescriptor$$anon$1
at java.io.ObjectStreamClass$FieldReflector.setObjFieldValues(ObjectStreamClass.java:2287)
at java.io.ObjectStreamClass.setObjFieldValues(ObjectStreamClass.java:1417)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2293)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2211)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2069)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2287)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2211)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2069)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1975)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1567)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2287)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2211)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2069)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2287)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2211)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2069)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
at com.package.structure.gateway.GatewayService$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$apply$4.apply(GatewayService.scala:76)
来源:https://stackoverflow.com/questions/57508461/what-causes-classcastexception-when-serializing-typetags