【发布时间】:2013-06-29 23:42:31
【问题描述】:
我需要创建一个java.lang.Class 的实例,它在其他方面与classOf[MyClass] 相同,但也有一个SerialVersionUID,MyClass 没有。 MyClass 是一个 Scala-2.10 类。一个问题是在 Java 中 SerialVersionUID 是 static final 而在 Scala 中 SerialVersionUID 因为 Scala 没有静态。
如果MyClass 是一个 Java 类,我想我可以使用 Javassist 做到这一点:
val ctclass = javassist.ClassPool.getDefault().get("mypackagage.MyClass")
val field = javassist.CtField.make(
"private static final long serialVersionUID = 1L;",
ctclass)
ctclass.addField(field)
val cls = ctclass.toClass()
但是,这对于 Scala 类来说并不适用。我尝试在 ClassLoader 中使用它进行反序列化。
反序列化过程中没有编译或运行时错误,但是反序列化的对象是不完整的,所以肯定有一些更微妙的问题。血淋淋的细节描述在here。大概问题出在Scala中如何处理static final字段以及Javassist只理解的事实
爪哇。我该怎么做才能使使用 Javassist 或任何其他方式的 Scala 类 100% 正确。
【问题讨论】:
-
您好,您能否详细说明您正在使用哪个工具进行反序列化以及您的课程在哪些方面不完整?只是一个猜测,但如果必要的信息不在字节码中,那么在腌制的 Scala 签名注释link 中不就是唯一可能的其他地方吗?也许您在腌制的 Scala 签名中遗漏了正确的信息? (我通过编写自己的 Scala 签名解决了类似的问题,我想看看这种方法是否更普遍)
-
@Julian Peeters,我使用的是纯 Java 序列化。我知道 MyClass 没有在源代码中指定
serialVersionUID,因此它使用基于默认哈希值的。问题是该类在库中的包之间移动,这也改变了它的默认serialVersionUID,即使该类的源在文本上保持相同。我很想看看你提到的问题和解决方案。 -
我的问题是我厌倦了将大型 json 模式转录到 Scala 案例类中,我通过在运行时定义和加载案例类以使用反射 (under constr'n) 进行实例化来解决它。我使用了 objectWeb 的 ASMifier 和一个完整的“diff -y”,但在我给它一个适当的 Scala 签名注释之前无法序列化生成的类。我正在使用专门挖掘 Scala sig 的 Salat 进行序列化,所以也许我只是在“寻找钉子”,但从长远来看,我认为“不完整”可能意味着“在 Scala sig 中缺少正确的信息”。跨度>
-
如果这是一个适合你的解决方案,目前我的工具严格限制为只有一个字段的案例类,因为 encoding issue(但如果你的类不是案例类并且是小),只测试泡菜机。而且到目前为止它还不能动态定义
defs,但是手动添加任何'def'也不会太糟糕。 -
PS 我对此很陌生,所以请不要犹豫,建议。例如,我是 Java 序列化的新手; this 似乎对我有用(即我不确定缺少什么?)
标签: scala serialization deserialization javassist bytecode-manipulation