Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to start a Scala akka actor

Tags:

scala

akka

Below class is causing an error at line new HelloWorld :

Exception in thread "main" akka.actor.ActorInitializationException: You cannot create an instance of [HelloWorld] explicitly using the constructor (new). You have to use one of the 'actorOf' factory methods to create a new actor. See the documentation.
  at akka.actor.ActorInitializationException$.apply(Actor.scala:219)
  at akka.actor.Actor$class.$init$(Actor.scala:436)
  at HelloWorld.<init>(HelloWorld.scala:4)
  at Driver$.main(HelloWorld.scala:38)
  at Driver.main(HelloWorld.scala)

So I try : val hw = actorOf(new HelloWorld) But this causes a compiler error :

not found: value actorOf

How should HelloWorld below be implemented ?

Reading other Scala docs an act method is requried to be defined within the class that extends Actor and then invoke the start method on this class, is there a reason for using actorOf instead of defining an act method ?

Below class is taken from Scala akka docs http://doc.akka.io/docs/akka/2.2.0/scala.html :

import akka.actor.Actor
import akka.actor.Actor._
import akka.actor.Props

class HelloWorld extends Actor {

  override def preStart(): Unit = {
    // create the greeter actor
    val greeter = context.actorOf(Props[Greeter], "greeter")
    // tell it to perform the greeting
    greeter ! Greeter.Greet
  }
  def receive = {
    // when the greeter is done, stop this actor and with it the application
    case Greeter.Done => context.stop(self)
  }

  object Greeter {   

    case object Greet
    case object Done


  }
  class Greeter extends Actor {
    def receive = {
      case Greeter.Greet =>
        println("Hello World!")
        sender ! Greeter.Done
    }
  }


}

object Driver {

    def main(args: Array[String]) {
      new HelloWorld
    }

}
like image 465
blue-sky Avatar asked Aug 03 '13 11:08

blue-sky


3 Answers

You need to edit your main as shown below. Secondly, in line-5, you need to change it to context.actorOf(Props(new Greeter)). This is because your Greeter does not have apply function defined, hence you need to manually create Greeter object yourself.

Working code below:

import akka.actor.ActorSystem

class HelloWorld extends Actor {

  override def preStart(): Unit = {
    // create the greeter actor
    val greeter = context.actorOf(Props(new Greeter), "greeter")//line 5
    // tell it to perform the greeting
    greeter ! Greeter.Greet
  }
  def receive = {
    // when the greeter is done, stop this actor and with it the application
    case Greeter.Done => context.stop(self)
  }

  object Greeter {   

    case object Greet
    case object Done


  }
  class Greeter extends Actor {
    def receive = {
      case Greeter.Greet =>
        println("Hello World!")
        sender ! Greeter.Done
    }
  }


}

object Driver {

    def main(args: Array[String]) {
      val system = ActorSystem("Main")
      val ac = system.actorOf(Props[HelloWorld])
    }

}
like image 167
Jatin Avatar answered Sep 30 '22 03:09

Jatin


If you want to use your main class do the following:

import akka.actor.{ActorSystem, Props}
object Driver extends App {    
    val system = ActorSystem("System")
    val hw = system.actorOf(Props[HelloWorld], name = "hw")
}

Which will create a new actor system and then create the HelloWorld actor using that actor system.

You can also follow the akka instructions: set Akka.Main as the main class and give the program "com.example.HelloWorld" as argument.

like image 35
some some Avatar answered Sep 30 '22 03:09

some some


val greeter = context.actorOf(Props(new Greeter), "greeter")//line 5

I don't think you need to have a new keyword there for Greeter. I believe the Props does that for you already. If anything having a new should be a

like image 37
Shiva Komat Avatar answered Sep 30 '22 04:09

Shiva Komat