7

EDIT Notice, I needed to make the reverse changes of this https://github.com/akka/akka/commit/ce014ece3568938b2036c4ccfd21b92faba69607#L13L6 to make the accepted answer work with AKKA 2.1 which is the stable distribution found on akkas homepage!


I have read all the tutorials I could find on AKKA, but nothing I found works "out of box".

Using eclipse, I want to create 2 programs.

Program1: starts actor "joe" and somehow makes it available on 127.0.0.1:some_port

Program2: gets a reference to actor "joe" at 127.0.0.1:some_port. Sends a hello message to "joe".

Program 1 should print something when the message is received. I want to run this example in eclipse using AKKA 2.1. Can someone list 2 programs, (program1 and program2) together with a working application.conf file that does this and nothing else?


edit> let me show you what I got so far:

actor

case class Greeting(who: String) extends Serializable

class GreetingActor extends Actor with ActorLogging {
  def receive = {
    case Greeting(who) ⇒ println("Hello " + who);log.info("Hello " + who)
  }
}

Program1:

package test

import akka.actor.ActorSystem

object Machine1 {

  def main(args: Array[String]): Unit = {
    val system = ActorSystem("MySystem")
  }

}

Program2

package test

import akka.actor.ActorSystem
import akka.actor.Props
import akka.actor.actorRef2Scala

object Machine2 {
  def main(args: Array[String]): Unit = {
    val system = ActorSystem("MySystem")
    val greeter = system.actorOf(Props[GreetingActor], name = "greeter")
    greeter ! Greeting("Felix")
  }
}

application.conf

akka {
  actor {
    deployment {
      /greeter {
        remote = "akka://MySystem@127.0.0.1:2553"
      }
    }
  }
}

However, this program works when I start only Program2 and it outputs:

Hello Felix
[INFO] [02/18/2013 12:27:29.999] [MySystem-akka.actor.default-dispatcher-2] [akka://MySystem/user/greeter] Hello Felix

It seems that it is not picking up my application.conf. I tried placing it both in the ./src/ and ./ folder of my eclipse project. No difference. Also, I know this is really demote deployment, but I need just a hello world program to work using AKKA. I spent so much time on this without getting a simple working application.

neatnick
  • 1,489
  • 1
  • 18
  • 29
Felix
  • 8,385
  • 10
  • 40
  • 59

4 Answers4

19

Update for Akka 2.2.3

A minimal remote application can be created as follows:

Create 2 Projects in Eclipse: Client and Server

Server:

The code for the server is

package server

import akka.actor.Actor
import akka.actor.ActorLogging
import akka.actor.ActorSystem
import akka.actor.Props

class Joe extends Actor {
  def receive = {
    case msg: String => println("joe received " + msg + " from " + sender)
    case _ => println("Received unknown msg ")
  }
}

object Server extends App {
  val system = ActorSystem("GreetingSystem")
  val joe = system.actorOf(Props[Joe], name = "joe")
  println(joe.path)
  joe ! "local msg!"
  println("Server ready")
}

The applincation.conf for the server is

akka {
  loglevel = "DEBUG"
  actor {
     provider = "akka.remote.RemoteActorRefProvider"
  }
  remote {
     enabled-transports = ["akka.remote.netty.tcp"]
     netty.tcp {
         hostname = "127.0.0.1"
         port = 2552
     }
     log-sent-messages = on
     log-received-messages = on
  }
}

Client:

The Client-code is

package client

import akka.actor._
import akka.actor.ActorDSL._

object Greet_Sender extends App {

   println("STARTING")

   implicit val system = ActorSystem("GreetingSystem-1")

   val joe = system.actorSelection("akka.tcp://GreetingSystem@127.0.0.1:2552/user/joe")

   println("That 's Joe:" + joe)

   val a = actor(new Act {
      whenStarting { joe ! "Hello Joe from remote" }
   })

   joe ! "Hello"

   println("Client has sent Hello to joe")
}

The client application.conf is:

akka {
  #log-config-on-start = on
  stdout-loglevel = "DEBUG"
  loglevel = "DEBUG"
  actor {
      provider = "akka.remote.RemoteActorRefProvider"
  }
  remote {
    enabled-transports = ["akka.remote.netty.tcp"]
    log-sent-messages = on
    log-received-messages = on
    netty.tcp {
          hostname = "127.0.0.1"
          port = 0
    }
  }  
}

Configurations have to be placed in two files called application.conf, both within the bin directory of the two projects.

6

As korefn mentioned, the remote documentation explains it's workings in detail. It also links to an example application. That example should give you everything you need to get started.


Edit

To get the sample application running perform the following steps:

Clone from GitHub

eecolor@BLACK:~/GihHub$ git clone https://github.com/akka/akka.git

Go into the akka directory and run sbt

eecolor@BLACK:~/GihHub/akka$ sbt

Switch to the akka-sample-project

akka > project akka-sample-remote

Call run on the project and select the CalcApp

Multiple main classes detected, select one to run:

 [1] sample.remote.calculator.java.JCreationApp
 [2] sample.remote.calculator.LookupApp
 [3] sample.remote.calculator.CalcApp
 [4] sample.remote.calculator.java.JLookupApp
 [5] sample.remote.calculator.CreationApp
 [6] sample.remote.calculator.java.JCalcApp

Enter number: 3

[info] Running sample.remote.calculator.CalcApp 
[INFO] [02/19/2013 19:22:09.055] [run-main] [Remoting] Starting remoting
[INFO] [02/19/2013 19:22:09.230] [run-main] [Remoting] Remoting started; listening on addresses :[akka.tcp://CalculatorApplication@127.0.0.1:2552]
Started Calculator Application - waiting for messages

Switch to another console and repeat the first few steps

eecolor@BLACK:~/GihHub/akka$ sbt
akka > project akka-sample-remote

Call run and select the LookupApp

akka-sample-remote > run

Multiple main classes detected, select one to run:

 [1] sample.remote.calculator.java.JCreationApp
 [2] sample.remote.calculator.LookupApp
 [3] sample.remote.calculator.CalcApp
 [4] sample.remote.calculator.java.JLookupApp
 [5] sample.remote.calculator.CreationApp
 [6] sample.remote.calculator.java.JCalcApp

Enter number: 2

[info] Running sample.remote.calculator.LookupApp 
[INFO] [02/19/2013 19:23:39.358] [run-main] [Remoting] Starting remoting
[INFO] [02/19/2013 19:23:39.564] [run-main] [Remoting] Remoting started; listening on addresses :[akka.tcp://LookupApplication@127.0.0.1:2553]
Started Lookup Application
Sub result: 14 - 16 = -2
Sub result: 13 - 22 = -9
Add result: 56 + 93 = 149
Add result: 18 + 19 = 37

Switch back to the other console and you should see something like this:

Calculating 14 - 16
Calculating 13 - 22
Calculating 56 + 93
Calculating 18 + 19
EECOLOR
  • 11,184
  • 3
  • 41
  • 75
  • The example doesn't teach me how to a) run a minimal akka remoting example without simple build tool, b) how akka locates the configuration file – Felix Feb 18 '13 at 17:02
  • [This part of the documentation](http://doc.akka.io/docs/akka/snapshot/general/configuration.html) tells you where the configuration comes from. There is no difference in running an application with Akka as compared to another java application. You could use something like [OneJar](https://github.com/sbt/sbt-onejar) to package your application into one jar. Make sure you read the warning in the configuration documentation about using OneJar with Akka. – EECOLOR Feb 18 '13 at 17:35
  • I can't run the remote example you linked me. I followed the guide exactly and I got this: felix@felix-UX32VD:~$ cd $AKKA_HOME felix@felix-UX32VD:~/akka-2.1.0$ sbt [info] Set current project to default-aac74b (in build file:/home/felix/akka-2.1.0/) > project akka-sample-remote [error] Not a valid project ID: akka-sample-remote [error] project akka-sample-remote [error] – Felix Feb 19 '13 at 11:03
  • I don't know what you did different than the explanation in the README inside the sample project, but following your guide works. Thank you very much! – Felix Feb 19 '13 at 22:01
  • Can you maybe give me a comment on why application.conf resides in "/resources/" when it the documentation clearly states it will look for it in the root of the classpath which should hardly be inside "/resources/"? – Felix Feb 19 '13 at 22:07
  • In sbt and maven the resource directory is where you store non-compiled files. sbt will then put those at the root of your `.jar` file when you package them. The `run` command simulates that they are at the root and thus placing non-compiled files in resources is equivalent to putting them into the root of the class path. [sbt directories](https://github.com/harrah/xsbt/wiki/Getting-Started-Directories) and [maven directories](http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html) might give you more information. – EECOLOR Feb 19 '13 at 22:15
0

Well, in your example, the Client code never references the config file and it won't work.

0

akka by default will use the application.conf file - so it does not need to be explicitly selected.

if one does want to then the code would be (taking the code above as an exmaple):

val configFile = getClass.getClassLoader.getResource("akka_local_application.conf").getFile
val config = ConfigFactory.parseFile(new File(configFile))
val system = ActorSystem("GreetingSystem",config)
val joe = system.actorOf(Props[Joe], name = "joe")
rak
  • 1