scala/akka 个案例 class 具有特征
scala/akka of case class with trait
我无法在使用 Akka 序列化的特征中获取大小写 类。以下代码按预期工作:
import akka.actor.ActorSystem
import akka.serialization.SerializationExtension
/*trait TestProtocol {*/
sealed abstract class Expr /* extends Serializable */
final case class Literal(v: Double) extends Expr
final case class Plus(a: Expr, b: Expr) extends Expr
final case class Minus(a: Expr, b: Expr) extends Expr
final case class Times(a: Expr, b: Expr) extends Expr
final case class Divide(a: Expr, b: Expr) extends Expr
/*}*/
class Foo /* extends Serializable with TestProtocol */ {
val system = ActorSystem("snitch")
def sample = List(
Plus(Literal(9),Literal(5)),
Times(Plus(Literal(1),Literal(18)),Literal(2))
)
val serialization = SerializationExtension(system)
val serializer = serialization.findSerializerFor(sample)
val bytes = serializer.toBinary(sample)
val back = serializer.fromBinary(bytes, manifest = None)
println(s">>>>>>> pre-serialize: ${sample}")
println(s">>>>>>> deserialized: ${back}")
}
object Main extends App {
val bar = new Foo
bar.system.terminate
}
但是如果我删除评论,就会抛出异常:
Exception in thread "main" java.io.NotSerializableException: akka.serialization.Serialization
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at scala.collection.immutable.List$SerializationProxy.writeObject(List.scala:468)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at akka.serialization.JavaSerializer$$anonfun$toBinary.apply$mcV$sp(Serializer.scala:235)
at akka.serialization.JavaSerializer$$anonfun$toBinary.apply(Serializer.scala:235)
at akka.serialization.JavaSerializer$$anonfun$toBinary.apply(Serializer.scala:235)
at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
at akka.serialization.JavaSerializer.toBinary(Serializer.scala:235)
at buggy.Foo.<init>(Main.scala:22)
at buggy.Main$.delayedEndpoint$buggy$Main(Main.scala:29)
尝试反序列化字节字符串时。即使在我尝试使任何相关的 类 可序列化(如评论中所示)之后,我也会得到异常。
有谁知道如何进行这项工作或为什么会失败?我正在使用 Scala 2.11.8 和 Akka 2.4.8;我用 sbt assembly 构建和测试...
非常感谢任何见解!
删除注释时出现异常的原因是,在该代码中,您正在制作正在序列化的 classes(Plus
、Minus
等...) class Foo
的一部分,因为你正在混合它们。因此,为了序列化那些 classes,封闭的 class 也必须是也连载了这就是为什么您首先必须让 Foo
继承自 Serializable
,这应该是第一个危险信号。现在,actor 系统和序列化扩展是 Foo
上的字段,因此序列化代码也需要序列化它们,这就是失败的来源。
您可以通过多种方式解决此问题。一种是将 TestProtocol
定义为 object
,然后将其导入到 Foo
中,而不是将其作为 trait
混合。如果你打算混合它,那么你可以让你的代码看起来像这样:
object Main extends App {
val bar = new Foo
bar.run
}
trait TestProtocol {
sealed abstract class Expr extends Serializable
final case class Literal(v: Double) extends Expr
final case class Plus(a: Expr, b: Expr) extends Expr
final case class Minus(a: Expr, b: Expr) extends Expr
final case class Times(a: Expr, b: Expr) extends Expr
final case class Divide(a: Expr, b: Expr) extends Expr
}
class Foo extends Serializable with TestProtocol {
def run = {
val system = ActorSystem("snitch")
def sample = List(
Plus(Literal(9),Literal(5)),
Times(Plus(Literal(1),Literal(18)),Literal(2))
)
val serialization = SerializationExtension(system)
val serializer = serialization.findSerializerFor(sample)
val bytes = serializer.toBinary(sample)
val back = serializer.fromBinary(bytes, manifest = None)
println(s">>>>>>> pre-serialize: ${sample}")
println(s">>>>>>> deserialized: ${back}")
system.terminate
}
}
这里,Foo
中没有字段,因为我已经将 actor 系统等推入了 run
方法。这只是解决您的问题的另一种方法。
我无法在使用 Akka 序列化的特征中获取大小写 类。以下代码按预期工作:
import akka.actor.ActorSystem
import akka.serialization.SerializationExtension
/*trait TestProtocol {*/
sealed abstract class Expr /* extends Serializable */
final case class Literal(v: Double) extends Expr
final case class Plus(a: Expr, b: Expr) extends Expr
final case class Minus(a: Expr, b: Expr) extends Expr
final case class Times(a: Expr, b: Expr) extends Expr
final case class Divide(a: Expr, b: Expr) extends Expr
/*}*/
class Foo /* extends Serializable with TestProtocol */ {
val system = ActorSystem("snitch")
def sample = List(
Plus(Literal(9),Literal(5)),
Times(Plus(Literal(1),Literal(18)),Literal(2))
)
val serialization = SerializationExtension(system)
val serializer = serialization.findSerializerFor(sample)
val bytes = serializer.toBinary(sample)
val back = serializer.fromBinary(bytes, manifest = None)
println(s">>>>>>> pre-serialize: ${sample}")
println(s">>>>>>> deserialized: ${back}")
}
object Main extends App {
val bar = new Foo
bar.system.terminate
}
但是如果我删除评论,就会抛出异常:
Exception in thread "main" java.io.NotSerializableException: akka.serialization.Serialization
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at scala.collection.immutable.List$SerializationProxy.writeObject(List.scala:468)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at akka.serialization.JavaSerializer$$anonfun$toBinary.apply$mcV$sp(Serializer.scala:235)
at akka.serialization.JavaSerializer$$anonfun$toBinary.apply(Serializer.scala:235)
at akka.serialization.JavaSerializer$$anonfun$toBinary.apply(Serializer.scala:235)
at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
at akka.serialization.JavaSerializer.toBinary(Serializer.scala:235)
at buggy.Foo.<init>(Main.scala:22)
at buggy.Main$.delayedEndpoint$buggy$Main(Main.scala:29)
尝试反序列化字节字符串时。即使在我尝试使任何相关的 类 可序列化(如评论中所示)之后,我也会得到异常。
有谁知道如何进行这项工作或为什么会失败?我正在使用 Scala 2.11.8 和 Akka 2.4.8;我用 sbt assembly 构建和测试...
非常感谢任何见解!
删除注释时出现异常的原因是,在该代码中,您正在制作正在序列化的 classes(Plus
、Minus
等...) class Foo
的一部分,因为你正在混合它们。因此,为了序列化那些 classes,封闭的 class 也必须是也连载了这就是为什么您首先必须让 Foo
继承自 Serializable
,这应该是第一个危险信号。现在,actor 系统和序列化扩展是 Foo
上的字段,因此序列化代码也需要序列化它们,这就是失败的来源。
您可以通过多种方式解决此问题。一种是将 TestProtocol
定义为 object
,然后将其导入到 Foo
中,而不是将其作为 trait
混合。如果你打算混合它,那么你可以让你的代码看起来像这样:
object Main extends App {
val bar = new Foo
bar.run
}
trait TestProtocol {
sealed abstract class Expr extends Serializable
final case class Literal(v: Double) extends Expr
final case class Plus(a: Expr, b: Expr) extends Expr
final case class Minus(a: Expr, b: Expr) extends Expr
final case class Times(a: Expr, b: Expr) extends Expr
final case class Divide(a: Expr, b: Expr) extends Expr
}
class Foo extends Serializable with TestProtocol {
def run = {
val system = ActorSystem("snitch")
def sample = List(
Plus(Literal(9),Literal(5)),
Times(Plus(Literal(1),Literal(18)),Literal(2))
)
val serialization = SerializationExtension(system)
val serializer = serialization.findSerializerFor(sample)
val bytes = serializer.toBinary(sample)
val back = serializer.fromBinary(bytes, manifest = None)
println(s">>>>>>> pre-serialize: ${sample}")
println(s">>>>>>> deserialized: ${back}")
system.terminate
}
}
这里,Foo
中没有字段,因为我已经将 actor 系统等推入了 run
方法。这只是解决您的问题的另一种方法。