java - 序列化 TypeTag 时导致 ClassCastException 的原因是什么?
问题描述
情况
我正在序列化这个类的一个实现:
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]]
}
并通过 REST 将其发送到网关,网关读取它以查找输入和输出状态的类型。(是的,我知道这不是一个很棒的设计)
结果
现在,如果我运行测试,同时启动网关和序列化 FnNamespace 的请求者,一切正常。
但是,如果我单独启动可执行文件,即可执行文件中的网关和另一个中的请求者,则会收到以下错误:
java.lang.ClassCastException:无法将 scala.reflect.api.SerializedTypeTag 的实例分配给 com.package.structure.FnDescriptor$ 实例中 scala.reflect.api.TypeTags$TypeTag 类型的字段 com.package.structure.FnDescriptor.inputTag $匿名$1
线索
我所做的研究表明,Serializer 使用 writeReplace 方法将 TypeTag 转换为 SerializedTypeTag。反序列化器应发生相应的 readResolve 以将 SerializedTypeTag 转换回 TypeTag,但它不会发生。相反,它会尝试将 SerializedTypeTag 分配给导致异常的 TypeTag。
它不会发生在单个 JVM 中的事实是我拥有的最好的线索,尽管我不知道如何解释它。
完整的堆栈跟踪
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)
解决方案
推荐阅读
- javascript - 如何将组件挂钩与 Formik handleSubmit 一起使用?
- linux - Ansible 创建用户并将他们分配到基于 vars 的特定组
- apache-kafka-streams - Kafka Stream:应用程序重启时的 Kafka Windowed Stream 行为
- javascript - 调用反应路由器链接时反应引导下拉菜单不会关闭
- google-cloud-platform - 从 GCP 向 Segment.io 发送 HTTP POST 请求
- mongodb - MongoDB $文本搜索未返回预期结果
- php - 在 Prestashop 1.7 的后台显示自定义挂钩
- flutter - 在 Flutter 中使用“bottomNavigationBar”后,“body”部分不可见
- python - 如何在 python 中用 2019-12-17T23:42:20Z 这种格式减去两个日期
- java - 来自嵌套 POJO 的比较器