简体   繁体   中英

Create an actor

This is probably an extremely simple error but I can't get it to work properly. I am using akka 2.2.3 to create an actor based application in scala.

The simplified setup is the following:

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)
    }
    ...
  }
}

And the main actor

class Discoverer extends Actor {
  override def preStart() = {
    val refresher = context.actorOf(Props[Refresher], "refresher")
    refresher ! Refresh
  }

  def receive = {
    case _ => sender ! Answer
  }
}

And the Refresher actor

 class Refresher extends Actor {
   ...
 }

What you should take away from this is that none of my actors has parameterized constructors.

However if I try to run my application it fails with

[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 []

What is my error here? Am I not supposed to create my actors with .actorOf(Props[Class], "actorname") ?

If you want to make this work with nested classes, you will need to instantiate the nested actor passing in a reference to the enclosing actor as a constructor arg. The error you are seeing is saying that there is no no-args constructor, so that's a hint. The code to make things work would look like this:

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 _ =>
    }
  }
}

My guess is that this has to do with trying to instantiate a non-static inner class (via reflection) without giving a reference to it's outer class. I determined this by reading through this post:

https://www.assembla.com/spaces/akka/tickets/3675#/activity/ticket :

Refresher is an inner class of Discoverer , therefor, if you want to create an instance of Refresher you need to do it in the context of an instance of Discoverer .

Take this example:

class A{
  class B{}
}

I can do new A , but new B will return an error. I have to do:

val a = new A
val b = new a.B

That's why akka failed to create this actor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM