5
votes

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
    }

}
3
act() and start() belong to the old and deprecated Scala actors, Akka is a different actor implementation, please refer to the docs at akka.io.Roland Kuhn
@RolandKuhn thanks for link, after some digging this doc is proving useful : doc.akka.io/docs/akka/snapshot/scala/actors.html#actors-scalablue-sky

3 Answers

8
votes

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

}
4
votes

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.

2
votes
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