我正在尝试使用 akka 远程角色发送消息,其中案例类是在其构造函数中接受参数的父类(super class)的子类。
这是重现问题的最小示例:
package com.tuvistavie.testremote
import akka.actor.{ Actor, ActorSystem, Props, ActorLogging }
import com.typesafe.config.ConfigFactory
abstract class Foo(val a: Int)
case class MessageFoo(override val a: Int) extends Foo(a)
object Sender {
def main(args: Array[String]) {
val system = ActorSystem("Sender", ConfigFactory.load.getConfig("sender"))
val actor = system.actorFor("akka://Receiver@127.0.0.1:2552/user/receiver")
actor ! MessageFoo(1)
}
}
object Receiver {
class ReceiverActor extends Actor with ActorLogging {
def receive = {
case m: MessageFoo => log.debug(m.toString)
}
}
def main(args: Array[String]) {
val system = ActorSystem("Receiver", ConfigFactory.load.getConfig("receiver"))
val actor = system.actorOf(Props[ReceiverActor], "receiver")
}
}
运行此代码时,出现以下错误:
[ERROR] [06/26/2013 02:53:16.132] [Receiver-9]
[NettyRemoteTransport(akka://Receiver@127.0.0.1:2552)]
RemoteServerError@akka://Receiver@127.0.0.1:2552] Error[java.io.InvalidClassException: com.tuvistavie.testremote.MessageFoo; no valid constructor]
我认为这是因为由于 parent 的构造函数,消息无法反序列化(使用
akka.serialization.JavaSerializer
)。如果只有一两条消息,我知道我可以编写自己的序列化程序,但是我的应用程序中有很多这样的案例类。
有没有什么简单的方法可以使用远程角色传递这种对象?
最佳答案
class A(a: Int)
case class C() extends A(1)
就像 cmbaxter 的回答指出的那样,这种模式,其中案例类的父类(super class)没有无参数构造函数,导致
InvalidClassException
关于反序列化。根据 cmbaxter 的回答,避免这种模式是一种解决方案。但是这种模式有什么问题呢?原因记录在 Serializable 的 API 文档中:
To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype's public, protected, and (if accessible) package fields. The subtype may assume this responsibility only if the class it extends has an accessible no-arg constructor to initialize the class's state. It is an error to declare a class Serializable if this is not the case. The error will be detected at runtime.
所以问题是
class A
没有无参数构造函数,而且它不是 Serializable
.所以一个简单的解决方案是让它Serializable
!class A(a: Int) extends Serializable
case class C() extends A(1)
关于scala - Akka 远程角色,没有默认构造函数的父类(super class),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17304620/