Akka Remote connection using Java

1,146 views
Skip to first unread message

reza shiftehfar

unread,
Mar 18, 2013, 11:00:18 PM3/18/13
to akka...@googlegroups.com, reza shiftehfar
I am new to Akka and am not familiar with Scala at all. I am trying to use the Akka+Java for running a project on multiple machines. I was able to successfully run Akka Java examples locally but when I tried to run any of them on two machine, the code stops working. I've looked at the Akka-Sample-Remote source code as well. It also works on a single machine but breaks when used on more than one machine. I think the problem is with the way I set the configurations. I have summarized the problem into a simple HelloWorld problem as below.

There code is divided into two projects with two separate configuration files: a Hello Actor project and a World Actor project. World Actor waits for receiving the Hello Message from the Hello Actor and then prints out the "Hello World". Here below you can see the code and the configuration for these two projects. As you can see, the World Actor is started on port 1719 and the Hello Actor starts on port 1720 and tries to connect to the World Actor using "akka.tcp://WorldApp...@192.27.336.187:1719/user/WorldActor" . Any idea on what is wrong with he code/configuration?

JWorld.java:

public class JWorld {

  public static void main(String[] args) {
    JWorldApplication app = new JWorldApplication();
    System.out.println("Started World Application - waiting for Hello message");
  }}

JWorldApplication.java:

import akka.actor.ActorRef;import akka.actor.ActorSystem;import akka.actor.Props;import com.typesafe.config.ConfigFactory;public class JWorldApplication {
  private ActorSystem system;

  public JWorldApplication() {
    system = ActorSystem.create("WorldApplication", ConfigFactory.load()
        .getConfig("WorldConfig"));
    ActorRef actor = system.actorOf(new Props(JWorldActor.class),
        "WorldActor");
  }}

JWolrdActor.java:

import akka.actor.UntypedActor;public class JWorldActor extends UntypedActor {
    @Override
    public void onReceive(Object message) {

        if (message instanceof HelloMessage) {
            HelloMessage recMsg = (HelloMessage) message;
            System.out.println("Received Message: " + recMsg.getText());
            System.out.println("***** Hello World! ******" );
        } else {
            System.out.println("UnHandled Message Received" );
            unhandled(message);
        }
    }}

HelloMessage.java:

import akka.actor.ActorRef; 

public class HelloMessage{
    private ActorRef receiver;
    private String text;
    HelloMessage() {}
    HelloMessage(ActorRef receiver){ this.receiver = receiver;}
    public ActorRef getReceiver(){ return receiver;}
    public void setText(String text) { this.text = text;}
    public String getText() {return text;}}

Application.conf:

WorldConfig {
  actor {
    provider = "akka.remote.RemoteActorRefProvider"
  }

  remote {
    netty.tcp {
      hostname="192.27.336.187"
      port=1719
    }
  }}

JHello.java:

public class JHello {public static void main(String[] args) {
    JHelloApplication testApp = new JHelloApplication();
    System.out.println("Started Hello Application - Sending Hello Message");
    testApp.sayHello();}}

JHelloApplication.java:

import akka.actor.ActorRef;import akka.actor.ActorSystem;import akka.actor.Props;import com.typesafe.config.ConfigFactory;public class JHelloApplication {
    private ActorSystem system;
    private ActorRef remoteActor, myActor;    public JHelloApplication() {
        system = ActorSystem.create("HelloApplication", ConfigFactory.load()
                .getConfig("HelloConfig"));
        myActor = system.actorOf(new Props(JHelloActor.class),"HelloActor");
        remoteActor = system
                .actorFor("akka.tcp://WorldApp...@192.27.336.187:1719/user/WorldActor");
    }

    public void sayHello() {
        myActor.tell(new HelloMessage(remoteActor));
    }}

JHelloActor.java:

import akka.actor.ActorRef;import akka.actor.UntypedActor;public class JHelloActor extends UntypedActor {

    @Override
    public void onReceive(Object message) {
        if (message instanceof HelloMessage) {
            HelloMessage msg = (HelloMessage) message;
            if (msg.getReceiver() !=null){
                msg.setText("Hello");
                msg.getReceiver().tell(msg, getSelf());
            }
        } else {
            System.out.println("UnHandled Message Received" );
            unhandled(message);
        }
    }}

application.conf:

HelloConfig {
  actor {
    provider = "akka.remote.RemoteActorRefProvider"
  }

  remote {
    netty.tcp {
      hostname="192.27.336.187"
      port=1720
    }
  }}
Thanks
Reza

Patrik Nordwall

unread,
Mar 19, 2013, 2:49:39 AM3/19/13
to akka...@googlegroups.com
Hi Reza,

I hope your Application.conf is named application.conf in reality.

You messages must be serializable. HelloMessage implements java.io.Serializable
What version of Akka are you using? I thought we had logging of that issue in 2.1.1 and 2.1.2.

Another thing that can be good to get correct from the beginning is that messages should be immutable.

/Patrik


--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://akka.io/faq/
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--

Patrik Nordwall
Typesafe The software stack for applications that scale
Twitter: @patriknw

Patrik Nordwall

unread,
Mar 19, 2013, 2:51:54 AM3/19/13
to akka...@googlegroups.com
Also, from your configuration it looks like you are using version 2.2-M1 or 2.2-M2. If you are using 2.1.2 your configuration is wrong (netty.tcp).

√iktor Ҡlang

unread,
Mar 19, 2013, 4:23:57 AM3/19/13
to Akka User List

Replace "akka.tcp" with "akka" in your actorFor. (Also, upgrade to 2.1.2 which would log this as an error)

Does that help?

Cheers, V

On Mar 19, 2013 9:20 AM, "Reza Shiftehfar" <r.shi...@gmail.com> wrote:
thanks Patrik.
I double checked and the config files are named application.conf in reality. I also revised the HelloMessage and it now implements Serializable. I also made them immutable.
Also, if it helps, when Hello Actor tries to connect, it fails as Actor[akka://WorldApplication/deadLetters]

In terms of versions, I am using Maven and so tried the code with different versions. Now I am using akka-actor 2.1.0 and akka-remote 2.1.1

<dependency>

<groupId>com.typesafe.akka</groupId>

<artifactId>akka-actor_2.10.0-RC5</artifactId>

<version>2.1.0-RC6</version>

</dependency>

<dependency>

<groupId>com.typesafe.akka</groupId>

<artifactId>akka-remote_2.10</artifactId>

<version>2.1.1</version>

</dependency>



On Tuesday, March 19, 2013 1:49:39 AM UTC-5, Patrik Nordwall wrote:
Hi Reza,

I hope your Application.conf is named application.conf in reality.

You messages must be serializable. HelloMessage implements java.io.Serializable
What version of Akka are you using? I thought we had logging of that issue in 2.1.1 and 2.1.2.

Another thing that can be good to get correct from the beginning is that messages should be immutable.

/Patrik
On Tue, Mar 19, 2013 at 2:04 AM, Reza Shiftehfar <r.shi...@gmail.com> wrote:

I am new to Akka and am not familiar with Scala at all. I am trying to use the Akka+Java for running a project on multiple machines. I was able to successfully run Akka Java examples locally but when I tried to run any of them on two machine, the code stops working. I've looked at the Akka-Sample-Remote source code as well. It also works on a single machine but breaks when used on more than one machine. I think the problem is with the way I set the configurations. I have summarized the problem into a simple HelloWorld problem as below.

There code is divided into two projects with two separate configuration files: a Hello Actor project and a World Actor project. World Actor waits for receiving the Hello Message from the Hello Actor and then prints out the "Hello World". Here below you can see the code and the configuration for these two projects. As you can see, the World Actor is started on port 1719 and the Hello Actor starts on port 1720 and tries to connect to the World Actor using "akka.tcp://WorldAp...@192.27.336.187:1719/user/WorldActor" . Any idea on what is wrong with he code/configuration?

Patrik Nordwall

unread,
Mar 19, 2013, 4:38:34 AM3/19/13
to akka...@googlegroups.com
Here is the exact dependency definition for maven: http://doc.akka.io/docs/akka/2.1.2/intro/getting-started.html#Using_Akka_with_Maven
As Viktor pointed out you must use "akka" instead of "akka.tcp" in actorFor. Make sure you use documentation and sample code that match the version you are using.

Patrik Nordwall

unread,
Mar 19, 2013, 6:45:09 AM3/19/13
to akka...@googlegroups.com
I will take a look at them.
/Patrik


On Tue, Mar 19, 2013 at 10:47 AM, Reza Shiftehfar <r.shi...@gmail.com> wrote:
thanks Patrik/Viktor:
I changed the "akka.tcp" to "akka" in the actorFor. Also, I changed the dependency accordingly to 2.1.2 but the problem still exists. I checked all the requirements and configuration with the 2.1.2 getting-started and remoting but still the same problem of not being connected to the remote actor (Actor[akka://helloapplication/deadLetters])? 

I am attaching the projects of the Hello and World to this post in case it helps. They are both Eclipse projects and can be opened in Eclipse.

thanks

                .actorFor("akka.tcp://WorldApplica...@192.27.336.187:1719/user/WorldActor");

Patrik Nordwall

unread,
Mar 19, 2013, 9:24:17 AM3/19/13
to akka...@googlegroups.com
The problem is that you have missed akka level in the application.conf files. It should be something like:
helloconfig {
  akka {
    actor {
      provider = "akka.remote.RemoteActorRefProvider"
    }
 
    remote {
      netty {
        hostname = "127.0.0.1"
      }
    }
  }
}

A scary thing is that you have the source for HelloMessage in both projects. You should add a dependency from hello to world instead, or place your shared classes (messages) in a third project.

/Patrik

√iktor Ҡlang

unread,
Mar 19, 2013, 1:26:25 PM3/19/13
to Akka User List
Hi Reza,

for debugging configuration, see this part of the documentation: http://doc.akka.io/docs/akka/2.1.2/general/configuration.html#Logging_of_Configuration

Cheers,


On Tue, Mar 19, 2013 at 6:20 PM, Reza Shiftehfar <r.shi...@gmail.com> wrote:
Wow. thanks Patrik. That solved the problem. I just wonder at what point, I removed that. thanks for spending time on this.

Also, in terms of defining HelloMessage in both projects, the reason is that the two projects go to two different machines. So, defining dependency/shared project between them won't work. Of course, at some point, I will create a sperate project for that and just shared that project but still that has to be copied to both places.

thanks



--
Viktor Klang
Director of Engineering

Twitter: @viktorklang

Patrik Nordwall

unread,
Mar 19, 2013, 2:01:04 PM3/19/13
to akka...@googlegroups.com


19 mar 2013 kl. 18:21 skrev Reza Shiftehfar <r.shi...@gmail.com>:

Wow. thanks Patrik. That solved the problem. I just wonder at what point, I removed that. thanks for spending time on this.

You are welcome. Happy hAkking!
/Patrik



Also, in terms of defining HelloMessage in both projects, the reason is that the two projects go to two different machines. So, defining dependency/shared project between them won't work. Of course, at some point, I will create a sperate project for that and just shared that project but still that has to be copied to both places.

thanks
Reply all
Reply to author
Forward
0 new messages