Search code examples
javaplayframework-2.0akkaactor

How to send a message to an actor from outside in Play Framework 2?


I am new to Akka and trying to write some code in Play Framework 2 in Java and use Akka. To create an actor and send a test message to it, I have:


public class Global extends GlobalSettings {

    @Override
    public void onStart(Application app) {
        final ActorRef testActor = Akka.system().actorOf(Props.create(TestActor.class), "testActor");
        testActor.tell("hi", ActorRef.noSender());
    }
}

This work perfectly fine and I see that my actor received my message, here is the code for my actor:


public class TestActor extends UntypedActor {

    @Override
    public void onReceive(Object message) throws Exception {
        if(message.toString().equals("hi")){
            System.out.println("I received a HI");
        }else{
            unhandled(message);
        }
    }
}

Very simple. However, If I try to send a message from a controller:


public static Result index() {
        final ActorRef testActor = Akka.system().actorFor("testActor");
        testActor.tell("hi", ActorRef.noSender());
        return ok(index.render("Your new application is ready."));
    }

I get this message on terminal:

[INFO] [09/20/2014 11:40:30.850] [application-akka.actor.default-dispatcher-4] [akka://application/testActor] Message [java.lang.String] from Actor[akka://application/deadLetters] to Actor[akka://application/testActor] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.

Can someone help me with this? why the first usage works and the second one fails? Thanks


Solution

  • The actorFor method requires the entire path, and your actor lives in the user space, so you have to use actorFor("/user/testActor"). Currently you are sending it to application/testActor, which would be a top-level actor in the ActorSystem itself.

    By the way, actorFor is deprecated (at least in the Scala API) and replaced by actorSelection.

    For more information, refer to the excellent documentation.