当前位置: 首页 > 知识库问答 >
问题:

scala序列化总是引发异常,为什么?

秦才
2023-03-14

我有一个小的scala代码snipet:

@SerialVersionUID(43L) class p(val a:Int=14,val b:Double=3.0) extends Serializable{
}
import java.io._

val out = new ObjectOutputStream(new FileOutputStream("my.obj"))
out.writeObject(new p(5,7))
out.close()

val in = new ObjectInputStream(new FileInputStream("my.obj"))
val savedPerson=in.readObject.asInstanceOf[p]
println(savedPerson.a)

当我在windows或mac上运行它时,它会打印出一个巨大的异常信息:

java.io.NotSerializableException: Main$$anon$1
    at java.base/java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.base/java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
    at java.base/java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.base/java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.base/java.io.ObjectOutputStream.writeObject(Unknown Source)
    at Main$$anon$1.errorFunction(ch09.scala:52)
    at Main$$anon$1.<init>(ch09.scala:110)
    at Main$.main(ch09.scala:1)
    at Main.main(ch09.scala)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.base/java.lang.reflect.Method.invoke(Unknown Source)
    at scala.reflect.internal.util.ScalaClassLoader.$anonfun$run$2(ScalaClassLoader.scala:98)
    at scala.reflect.internal.util.ScalaClassLoader.asContext(ScalaClassLoader.scala:32)
    at scala.reflect.internal.util.ScalaClassLoader.asContext$(ScalaClassLoader.scala:30)
    at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:129)
    at scala.reflect.internal.util.ScalaClassLoader.run(ScalaClassLoader.scala:98)
    at scala.reflect.internal.util.ScalaClassLoader.run$(ScalaClassLoader.scala:90)
    at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:129)
    at scala.tools.nsc.CommonRunner.run(ObjectRunner.scala:22)
    at scala.tools.nsc.CommonRunner.run$(ObjectRunner.scala:21)
    at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:39)
    at scala.tools.nsc.CommonRunner.runAndCatch(ObjectRunner.scala:29)
    at scala.tools.nsc.CommonRunner.runAndCatch$(ObjectRunner.scala:28)
    at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:39)
    at scala.tools.nsc.ScriptRunner.runCompiled(ScriptRunner.scala:170)
    at scala.tools.nsc.ScriptRunner.$anonfun$runScript$1(ScriptRunner.scala:187)
    at scala.tools.nsc.ScriptRunner.$anonfun$runScript$1$adapted(ScriptRunner.scala:187)
    at scala.tools.nsc.ScriptRunner.$anonfun$withCompiledScript$2(ScriptRunner.scala:156)
    at scala.tools.nsc.ScriptRunner.runScript(ScriptRunner.scala:124)
    at scala.tools.nsc.ScriptRunner.runScriptAndCatch(ScriptRunner.scala:200)
    at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:70)
    at scala.tools.nsc.MainGenericRunner.run$1(MainGenericRunner.scala:85)
    at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
    at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:101)
    at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

这是什么错误?我该如何修复它?我不太明白。谢谢!

共有1个答案

阎咏思
2023-03-14

我从您的堆栈跟踪中看到您正在使用脚本运行程序:

scala-nc noser。scala

我将脚本命名为Yessir,没有,先生,因为没有发生序列化。

nc避免启动编译服务器守护进程。

如果脚本运行器没有看到具有主方法的对象,它会将脚本代码打包到它为您构建的主方法的局部类中。

def main(args:Array[String])={class anon\u class{code};新建anon\u class()}

您的代码在构造函数中运行,这也不是一个好主意。

您可以通过Xprint看到这一点:typer,flatten。或者用Xprint:all进行实验。

您的可序列化类有一个指向匿名本地类的外部指针,并且匿名类不可序列化。

也许外部指针只是一个错误。或者不是,请参阅下面的参考。它需要一个提示来消除外部指针,例如使类最终

我看到也有类似的错误,比如这个错误,封闭模块被lambda捕获。

您的解决方法是将代码放在对象的主方法中,或将所有内容包装在应用程序中。

object Main extends App {
  // code
}

另一种解决方法是使可序列化类成为final。对该票据以及相关票据和修复进行了讨论。

 类似资料:
  • 我正在尝试反序列化以下JSON: 通过此方法调用: 方法: 不幸的是,我得到了以下错误: System.Text.Json.JsonException:'JSON 值无法转换为 System.DateTime。路径:$。出版|行号: 0 |BytePositionInLine: 353.' JSON 来自对以下 API 方法的调用: 是正常的 属性 我做错了什么?如何将JSON的<code>pub

  • 我们使用的是基于Spark Streaming接收器的方法,我们刚刚启用了检查指向来解决数据丢失问题。 火花版本是,我们正在接收来自Kafka主题的消息。 我在内部使用了,方法,所以它抛出了不可序列化的异常。 我试图扩展可序列化的类,但仍然是相同的错误。只有当我们启用检查点时,才会发生这种情况。 错误日志: 2017-02-08 22:53:53250错误[驱动程序]流媒体。StreamingCo

  • 问题内容: 我正在使用Newtonsoft JSON序列化程序,它适用于大多数对象。 不幸的是,当我尝试序列化一个大对象时,我得到了一个,其中一个成员抛出。 无论如何,有没有要忽略有问题的成员并序列化对象的其余部分? 我在想吗? 这是我想要做的简化版本: 这是堆栈跟踪: 如果有人知道可以执行此操作,我很乐意使用其他JSON序列化程序。 问题答案: 如果您不控制源代码,则可以在序列化过程中使用自定义

  • 问题在于Spark数据集和INT列表的序列化。Scala版本是2.10.4,Spark版本是1.6。 这和其他问题类似,但是我不能基于这些回答让它工作。我已经简化了代码,以便仅仅显示问题。 我有一门案例课: 我的主要方法是: 我得到以下错误: 如果我从FlightExt中删除列表,那么一切正常,这表明lambda函数序列化没有问题。 Scala本身似乎序列化了一系列Int的优点。也许Spark在序

  • 问题内容: 当您使用Exception类扩展一个类(用于创建新的异常)时,会收到警告,提示您有一个。我知道这在序列化和反序列化过程中起着重要的作用,但是何时需要序列化我的Exception?谁能给我一个实际的案例,让我的自定义异常类具有序列化和反序列化? 问题答案: 这是因为所有异常的根类都实现了接口。默认情况下,所有异常都是可序列化的,这是一种语言设计决策,因为作者希望异常能够在没有任何特殊配置

  • 当尝试使用neo4j-harness测试neo4j服务器时,我在构建嵌入式Neo4j服务器时收到异常 我的pom.xml是这样的: