这可能是一个非常简单的错误,但我无法让它正常工作。 我正在使用akka 2.2.3在scala中创建一个基于actor的应用程序。
简化设置如下:
object Main {
def main(args: Array[String]) = {
val system = ActorSystem("Test")
val discoverer = system.actorOf(Props[Discoverer], "discoverer")
implicit val timeout = Timeout(5.seconds)
val not = discoverer ? Messages.Find(something)
not.onComplete {
case Success(va) => println(va)
case Failure(err) => println(err)
}
...
}
}
主要演员
class Discoverer extends Actor {
override def preStart() = {
val refresher = context.actorOf(Props[Refresher], "refresher")
refresher ! Refresh
}
def receive = {
case _ => sender ! Answer
}
}
Refresher
演员
class Refresher extends Actor {
...
}
你应该从中得到的是,我的演员都没有参数化构造函数。
但是,如果我尝试运行我的应用程序,则会失败
[ERROR] [12/09/2013 13:17:06.893] [Test-akka.actor.default-dispatcher-3]
[akka://Test/user/discoverer] no matching constructor found on
class Discoverer$Refresher for arguments []
我的错误是什么?我不应该用.actorOf(Props[Class], "actorname")
创建我的演员吗?
答案 0 :(得分:12)
如果要使用嵌套类进行此操作,则需要实例化嵌套的actor,将对封闭actor的引用作为构造函数arg传递。您看到的错误是说没有no-args
构造函数,所以这是一个提示。使事情有效的代码如下所示:
object InnerTest {
def main(args: Array[String]) {
val sys = ActorSystem("test")
sys.actorOf(Props[OuterActor])
}
}
class OuterActor extends Actor{
override def preStart = {
context.actorOf(Props(classOf[InnerActor], this), "my-inner-actor")
}
def receive = {
case _ =>
}
class InnerActor extends Actor{
def receive = {
case _ =>
}
}
}
我的猜测是,这与尝试实例化非静态内部类(通过反射)而不提供对它的外部类的引用有关。我通过阅读这篇文章来确定这一点:
https://www.assembla.com/spaces/akka/tickets/3675#/activity/ticket:
答案 1 :(得分:0)
Refresher
是Discoverer
的内部类,因此,如果要创建Refresher
的实例,则需要在Discoverer
的实例的上下文中执行此操作}。
举个例子:
class A{
class B{}
}
我可以new A
,但new B
会返回错误。我必须这样做:
val a = new A
val b = new a.B
这就是akka未能创造这个演员的原因。