首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Akka远程参与者,没有默认构造函数的超类

Akka远程参与者,没有默认构造函数的超类
EN

Stack Overflow用户
提问于 2013-06-26 02:15:16
回答 2查看 1.3K关注 0票数 7

我正在尝试使用akka远程actors发送消息,其中case类是在其构造函数中接受参数的超类的子类。

以下是重现该问题的最小示例:

代码语言:javascript
复制
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")
  }
}

当运行这段代码时,我得到以下错误:

代码语言:javascript
复制
[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]

我认为这是因为消息不能反序列化(使用akka.serialization.JavaSerializer),因为父类的构造函数。如果只有一两条消息,我知道我可以编写自己的序列化程序,但我的应用程序中有很多这样的case类。

有什么简单的方法可以使用远程角色来传递这种对象吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-26 03:16:23

如果你像这样重组,事情就会变得更好:

代码语言:javascript
复制
trait Foo{
  val a:Int
}
case class MessageFoo(a:Int) extends Foo

我通常会尽量避免使用case类来继承类。如果我需要能够将一组case类作为抽象类型引用,我会使用特征。

票数 9
EN

Stack Overflow用户

发布于 2015-01-28 18:54:25

代码语言:javascript
复制
class A(a: Int)
case class C() extends A(1)

正如cmbaxter的答案所指出的那样,这种模式,其中case类的超类没有无参数构造函数,会导致反序列化时出现InvalidClassException。根据cmbaxter的回答,避免这种模式是一种解决方案。

但是这个模式有什么问题呢?Serializable的API文档中记录了原因

为了允许非序列化类的子类型被序列化,该子类型可以承担保存和恢复超类型的公共、受保护和(如果可访问)包字段的状态的责任。只有当它扩展的类具有可访问的无参数构造函数来初始化类的状态时,子类型才可以承担这一责任。如果不是这样,那么声明一个类Serializable是错误的。错误将在运行时被检测到。

所以问题是class A没有无参数的构造函数,而且它也不是Serializable。所以一个简单的解决方案就是让它成为Serializable

代码语言:javascript
复制
class A(a: Int) extends Serializable
case class C() extends A(1)
票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17304620

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档