=doc #3689 Make activator template for akka.Main

This commit is contained in:
Patrik Nordwall 2013-11-15 11:53:21 +01:00
parent 8b6b2965e5
commit 362074177a
25 changed files with 428 additions and 184 deletions

2
.gitignore vendored
View file

@ -71,3 +71,5 @@ tm*.lck
tm*.log tm*.log
tm.out tm.out
worker*.log worker*.log
*-shim.sbt

View file

@ -2,42 +2,17 @@
The Obligatory Hello World The Obligatory Hello World
########################## ##########################
Since every programming paradigm needs to solve the tough problem of printing a The actor based version of the tough problem of printing a
well-known greeting to the console well introduce you to the actor-based well-known greeting to the console is introduced in a `Typesafe Activator <http://typesafe.com/platform/getstarted>`_
version. tutorial named `Akka Main in Java <http://typesafe.com/activator/template/akka-sample-main-java>`_.
.. includecode:: ../java/code/docs/actor/japi/HelloWorld.java#hello-world The tutorial illustrates the generic launcher class :class:`akka.Main` which expects only
The ``HelloWorld`` actor is the applications “main” class; when it terminates
the application will shut down—more on that later. The main business logic
happens in the :meth:`preStart` method, where a ``Greeter`` actor is created
and instructed to issue that greeting we crave for. When the greeter is done it
will tell us so by sending back a message, and when that message has been
received it will be passed into the :meth:`onReceive` method where we can
conclude the demonstration by stopping the ``HelloWorld`` actor. You will be
very curious to see how the ``Greeter`` actor performs the actual task:
.. includecode:: ../java/code/docs/actor/japi/Greeter.java#greeter
This is extremely simple now: after its creation this actor will not do
anything until someone sends it a message, and if that happens to be an
invitation to greet the world then the ``Greeter`` complies and informs the
requester that the deed has been done.
As a Java developer you will probably want to tell us that there is no
``static public void main(...)`` anywhere in these classes, so how do we run
this program? The answer is that the appropriate :meth:`main` method is
implemented in the generic launcher class :class:`akka.Main` which expects only
one command line argument: the class name of the applications main actor. This one command line argument: the class name of the applications main actor. This
main method will then create the infrastructure needed for running the actors, main method will then create the infrastructure needed for running the actors,
start the given main actor and arrange for the whole application to shut down start the given main actor and arrange for the whole application to shut down
once the main actor terminates. Thus you will be able to run the above code once the main actor terminates.
with a command similar to the following::
java -classpath <all those JARs> akka.Main com.example.HelloWorld There is also another `Typesafe Activator <http://typesafe.com/platform/getstarted>`_
tutorial in the same problem domain that is named `Hello Akka! <http://typesafe.com/activator/template/hello-akka>`_.
This conveniently assumes placement of the above class definitions in package It describes the basics of Akka in more depth.
``com.example`` and it further assumes that you have the required JAR files for
``scala-library`` and ``akka-actor`` available. The easiest would be to manage
these dependencies with a build tool, see :ref:`build-tool`.

View file

@ -1,50 +0,0 @@
/**
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
*/
package docs.actor
import akka.testkit.AkkaSpec
//#hello-world
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)
}
}
//#hello-world
//#greeter
object Greeter {
case object Greet
case object Done
}
class Greeter extends Actor {
def receive = {
case Greeter.Greet
println("Hello World!")
sender ! Greeter.Done
}
}
//#greeter
class IntroDocSpec extends AkkaSpec {
"demonstrate HelloWorld" in {
expectTerminated(watch(system.actorOf(Props[HelloWorld])))
}
}

View file

@ -2,43 +2,17 @@
The Obligatory Hello World The Obligatory Hello World
########################## ##########################
Since every programming paradigm needs to solve the tough problem of printing a The actor based version of the tough problem of printing a
well-known greeting to the console well introduce you to the actor-based well-known greeting to the console is introduced in a `Typesafe Activator <http://typesafe.com/platform/getstarted>`_
version. tutorial named `Akka Main in Scala <http://typesafe.com/activator/template/akka-sample-main-scala>`_.
.. includecode:: ../scala/code/docs/actor/IntroDocSpec.scala#hello-world The tutorial illustrates the generic launcher class :class:`akka.Main` which expects only
one command line argument: the class name of the applications main actor. This
main method will then create the infrastructure needed for running the actors,
start the given main actor and arrange for the whole application to shut down
once the main actor terminates.
The ``HelloWorld`` actor is the applications “main” class; when it terminates There is also another `Typesafe Activator <http://typesafe.com/platform/getstarted>`_
the application will shut down—more on that later. The main business logic tutorial in the same problem domain that is named `Hello Akka! <http://typesafe.com/activator/template/hello-akka>`_.
happens in the :meth:`preStart` method, where a ``Greeter`` actor is created It describes the basics of Akka in more depth.
and instructed to issue that greeting we crave for. When the greeter is done it
will tell us so by sending back a message, and when that message has been
received it will be passed into the behavior described by the :meth:`receive`
method where we can conclude the demonstration by stopping the ``HelloWorld``
actor. You will be very curious to see how the ``Greeter`` actor performs the
actual task:
.. includecode:: ../scala/code/docs/actor/IntroDocSpec.scala#greeter
This is extremely simple now: after its creation this actor will not do
anything until someone sends it a message, and if that happens to be an
invitation to greet the world then the ``Greeter`` complies and informs the
requester that the deed has been done.
As a Scala developer you will probably want to tell us that there is no
``main(Array[String])`` method anywhere in these classes, so how do we run this
program? The answer is that the appropriate :meth:`main` method is implemented
in the generic launcher class :class:`akka.Main` which expects only one command
line argument: the class name of the applications main actor. This main method
will then create the infrastructure needed for running the actors, start the
given main actor and arrange for the whole application to shut down once the
main actor terminates. Thus you will be able to run the above code with a
command similar to the following::
java -classpath <all those JARs> akka.Main com.example.HelloWorld
This conveniently assumes placement of the above class definitions in package
``com.example`` and it further assumes that you have the required JAR files for
``scala-library`` and ``akka-actor`` available. The easiest would be to manage
these dependencies with a build tool, see :ref:`build-tool`.

View file

@ -1,13 +0,0 @@
HELLO
=====
This sample is meant to be used by studying the code; it does not perform any
astounding functions when running it. If you want to run it, check out the akka
sources on your local hard drive, follow the [instructions for setting up Akka
with SBT](http://doc.akka.io/docs/akka/current/intro/getting-started.html).
When you start SBT within the checked-out akka source directory, you can run
this sample by typing
akka-sample-hello/run
You can read more in the [Akka docs](http://akka.io/docs).

View file

@ -1,32 +0,0 @@
/**
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
*/
package sample.hello
import akka.actor.{ ActorSystem, Actor, Props }
case object Start
object Main {
def main(args: Array[String]): Unit = {
val system = ActorSystem()
system.actorOf(Props[HelloActor]) ! Start
}
}
class HelloActor extends Actor {
val worldActor = context.actorOf(Props[WorldActor])
def receive = {
case Start worldActor ! "Hello"
case s: String
println("Received message: %s".format(s))
context.system.shutdown()
}
}
class WorldActor extends Actor {
def receive = {
case s: String sender ! s.toUpperCase + " world!"
}
}

View file

@ -0,0 +1,13 @@
Copyright 2013 Typesafe, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -0,0 +1,4 @@
name=akka-sample-main-java
title=Akka Main in Java
description=Actor based version of obligatory Hello World program using the generic launcher class akka.Main.
tags=Basics,akka,java,java,starter

View file

@ -0,0 +1,10 @@
name := "akka-sample-main-java"
version := "1.0"
scalaVersion := "2.10.3"
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor" % "2.3-SNAPSHOT"
)

View file

@ -0,0 +1 @@
sbt.version=0.13.0

View file

@ -1,26 +1,23 @@
/** /**
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
*/ */
package sample.hello;
package docs.actor.japi;
import akka.actor.UntypedActor; import akka.actor.UntypedActor;
import java.io.Serializable;
//#greeter
public class Greeter extends UntypedActor { public class Greeter extends UntypedActor {
public static enum Msg { public static enum Msg {
GREET, DONE; GREET, DONE;
} }
@Override @Override
public void onReceive(Object msg) { public void onReceive(Object msg) {
if (msg == Msg.GREET) { if (msg == Msg.GREET) {
System.out.println("Hello World!"); System.out.println("Hello World!");
getSender().tell(Msg.DONE, getSelf()); getSender().tell(Msg.DONE, getSelf());
} else unhandled(msg); } else
unhandled(msg);
} }
} }
//#greeter

View file

@ -2,9 +2,8 @@
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
*/ */
package docs.actor.japi; package sample.hello;
//#hello-world
import akka.actor.Props; import akka.actor.Props;
import akka.actor.UntypedActor; import akka.actor.UntypedActor;
import akka.actor.ActorRef; import akka.actor.ActorRef;
@ -14,8 +13,7 @@ public class HelloWorld extends UntypedActor {
@Override @Override
public void preStart() { public void preStart() {
// create the greeter actor // create the greeter actor
final ActorRef greeter = final ActorRef greeter = getContext().actorOf(Props.create(Greeter.class), "greeter");
getContext().actorOf(Props.create(Greeter.class), "greeter");
// tell it to perform the greeting // tell it to perform the greeting
greeter.tell(Greeter.Msg.GREET, getSelf()); greeter.tell(Greeter.Msg.GREET, getSelf());
} }
@ -25,7 +23,7 @@ public class HelloWorld extends UntypedActor {
if (msg == Greeter.Msg.DONE) { if (msg == Greeter.Msg.DONE) {
// when the greeter is done, stop this actor and with it the application // when the greeter is done, stop this actor and with it the application
getContext().stop(getSelf()); getContext().stop(getSelf());
} else unhandled(msg); } else
unhandled(msg);
} }
} }
//#hello-world

View file

@ -0,0 +1,11 @@
/**
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
*/
package sample.hello;
public class Main {
public static void main(String[] args) {
akka.Main.main(new String[] { HelloWorld.class.getName() });
}
}

View file

@ -0,0 +1,43 @@
/**
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
*/
package sample.hello;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.actor.Terminated;
import akka.actor.UntypedActor;
import akka.event.Logging;
import akka.event.LoggingAdapter;
public class Main2 {
public static void main(String[] args) {
ActorSystem system = ActorSystem.create("Hello");
ActorRef a = system.actorOf(Props.create(HelloWorld.class), "helloWorld");
system.actorOf(Props.create(Terminator.class, a), "terminator");
}
public static class Terminator extends UntypedActor {
private final LoggingAdapter log = Logging.getLogger(getContext().system(), this);
private final ActorRef ref;
public Terminator(ActorRef ref) {
this.ref = ref;
getContext().watch(ref);
}
@Override
public void onReceive(Object msg) {
if (msg instanceof Terminated) {
log.info("{} has terminated, shutting down system", ref.path());
getContext().system().shutdown();
} else {
unhandled(msg);
}
}
}
}

View file

@ -0,0 +1,96 @@
<!-- <html> -->
<head>
<title>The Obligatory Hello World</title>
</head>
<body>
<div>
<h2>The Obligatory Hello World</h2>
<p>
Since every programming paradigm needs to solve the tough problem of printing a
well-known greeting to the console well introduce you to the actor-based
version.
</p>
<p>
Open <a href="#code/src/main/java/sample/hello/HelloWorld.java" class="shortcut">HelloWorld.java</a>
</p>
<p>
The <code>HelloWorld</code> actor is the applications “main” class; when it terminates
the application will shut down—more on that later. The main business logic
happens in the <code>preStart</code> method, where a <code>Greeter</code> actor is created
and instructed to issue that greeting we crave for. When the greeter is done it
will tell us so by sending back a message, and when that message has been
received it will be passed into the behavior described by the <code>receive</code>
method where we can conclude the demonstration by stopping the <code>HelloWorld</code>
actor.
</p>
</div>
<div>
<h2>The Greeter</h2>
<p>
You will be very curious to see how the <code>Greeter</code> actor performs the
actual task. Open <a href="#code/src/main/java/sample/hello/Greeter.java" class="shortcut">Greeter.java</a>.
</p>
<p>
This is extremely simple now: after its creation this actor will not do
anything until someone sends it a message, and if that happens to be an
invitation to greet the world then the <code>Greeter</code> complies and informs the
requester that the deed has been done.
</p>
</div>
<div>
<h2>Main class</h2>
<p>
Go to the <a href="#run" class="shortcut">Run</a> tab, and start the application main class
<code>sample.hello.Main</code>. In the log output you can see the "Hello World!" greeting.
</p>
<p>
<a href="#code/src/main/java/sample/hello/Main.java" class="shortcut">Main.java</a>
is actually just a small wrapper around the generic launcher class <code>akka.Main</code>,
which expects only one argument: the class name of the applications main actor. This main
method will then create the infrastructure needed for running the actors, start the
given main actor and arrange for the whole application to shut down once the
main actor terminates. Thus you will be able to run the application with a
command similar to the following:
</p>
<pre><code>
java -classpath <all those JARs> akka.Main sample.hello.HelloWorld
</code></pre>
<p>
This conveniently assumes placement of the above class definitions in package
<code>sample.hello</code> and it further assumes that you have the required JAR files for
<code>scala-library</code>, <code>typesafe-config</code> and <code>akka-actor</code> available.
The easiest would be to manage these dependencies with a
<a href="http://doc.akka.io/docs/akka/2.3-SNAPSHOT/intro/getting-started.html#Using_a_build_tool" target="_blank">build tool</a>.
</p>
<p>
If you need more control of the startup code than what is provided by <code>akka.Main</code>
you can easily write your own main class such as
<a href="#code/src/main/java/sample/hello/Main2.java" class="shortcut">Main2.java</a>
</p>
<p>
Try to run the <code>sample.hello.Main2</code> class
by selecting it in the 'Main class' menu in the <a href="#run" class="shortcut">Run</a> tab.
</p>
</div>
</body>
</html>

View file

@ -0,0 +1,13 @@
Copyright 2013 Typesafe, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -0,0 +1,4 @@
name=akka-sample-main-scala
title=Akka Main in Scala
description=Actor based version of obligatory Hello World program using the generic launcher class akka.Main.
tags=Basics,akka,java,scala,starter

View file

@ -0,0 +1,10 @@
name := "akka-sample-main-scala"
version := "1.0"
scalaVersion := "2.10.3"
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor" % "2.3-SNAPSHOT"
)

View file

@ -0,0 +1 @@
sbt.version=0.13.0

View file

@ -0,0 +1,19 @@
/**
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
*/
package sample.hello
import akka.actor.Actor
object Greeter {
case object Greet
case object Done
}
class Greeter extends Actor {
def receive = {
case Greeter.Greet
println("Hello World!")
sender ! Greeter.Done
}
}

View file

@ -0,0 +1,23 @@
/**
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
*/
package sample.hello
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)
}
}

View file

@ -0,0 +1,12 @@
/**
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
*/
package sample.hello
object Main {
def main(args: Array[String]): Unit = {
akka.Main.main(Array(classOf[HelloWorld].getName))
}
}

View file

@ -0,0 +1,30 @@
/**
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
*/
package sample.hello
import akka.actor.ActorSystem
import akka.actor.Props
import akka.actor.ActorRef
import akka.actor.Actor
import akka.actor.ActorLogging
import akka.actor.Terminated
object Main2 {
def main(args: Array[String]): Unit = {
val system = ActorSystem("Hello")
val a = system.actorOf(Props[HelloWorld], "helloWorld")
system.actorOf(Props(classOf[Terminator], a), "terminator")
}
class Terminator(ref: ActorRef) extends Actor with ActorLogging {
context watch ref
def receive = {
case Terminated(_)
log.info("{} has terminated, shutting down system", ref.path)
context.system.shutdown()
}
}
}

View file

@ -0,0 +1,96 @@
<!-- <html> -->
<head>
<title>The Obligatory Hello World</title>
</head>
<body>
<div>
<h2>The Obligatory Hello World</h2>
<p>
Since every programming paradigm needs to solve the tough problem of printing a
well-known greeting to the console well introduce you to the actor-based
version.
</p>
<p>
Open <a href="#code/src/main/scala/sample/hello/HelloWorld.scala" class="shortcut">HelloWorld.scala</a>
</p>
<p>
The <code>HelloWorld</code> actor is the applications “main” class; when it terminates
the application will shut down—more on that later. The main business logic
happens in the <code>preStart</code> method, where a <code>Greeter</code> actor is created
and instructed to issue that greeting we crave for. When the greeter is done it
will tell us so by sending back a message, and when that message has been
received it will be passed into the behavior described by the <code>receive</code>
method where we can conclude the demonstration by stopping the <code>HelloWorld</code>
actor.
</p>
</div>
<div>
<h2>The Greeter</h2>
<p>
You will be very curious to see how the <code>Greeter</code> actor performs the
actual task. Open <a href="#code/src/main/scala/sample/hello/Greeter.scala" class="shortcut">Greeter.scala</a>.
</p>
<p>
This is extremely simple now: after its creation this actor will not do
anything until someone sends it a message, and if that happens to be an
invitation to greet the world then the <code>Greeter</code> complies and informs the
requester that the deed has been done.
</p>
</div>
<div>
<h2>Main class</h2>
<p>
Go to the <a href="#run" class="shortcut">Run</a> tab, and start the application main class
<code>sample.hello.Main</code>. In the log output you can see the "Hello World!" greeting.
</p>
<p>
<a href="#code/src/main/scala/sample/hello/Main.scala" class="shortcut">Main.scala</a>
is actually just a small wrapper around the generic launcher class <code>akka.Main</code>,
which expects only one argument: the class name of the applications main actor. This main
method will then create the infrastructure needed for running the actors, start the
given main actor and arrange for the whole application to shut down once the
main actor terminates. Thus you will be able to run the application with a
command similar to the following:
</p>
<pre><code>
java -classpath <all those JARs> akka.Main sample.hello.HelloWorld
</code></pre>
<p>
This conveniently assumes placement of the above class definitions in package
<code>sample.hello</code> and it further assumes that you have the required JAR files for
<code>scala-library</code>, <code>typesafe-config</code> and <code>akka-actor</code> available.
The easiest would be to manage these dependencies with a
<a href="http://doc.akka.io/docs/akka/2.3-SNAPSHOT/intro/getting-started.html#Using_a_build_tool" target="_blank">build tool</a>.
</p>
<p>
If you need more control of the startup code than what is provided by <code>akka.Main</code>
you can easily write your own main class such as
<a href="#code/src/main/scala/sample/hello/Main2.scala" class="shortcut">Main2.scala</a>
</p>
<p>
Try to run the <code>sample.hello.Main2</code> class
by selecting it in the 'Main class' menu in the <a href="#run" class="shortcut">Run</a> tab.
</p>
</div>
</body>
</html>

View file

@ -446,7 +446,7 @@ object AkkaBuild extends Build {
id = "akka-samples", id = "akka-samples",
base = file("akka-samples"), base = file("akka-samples"),
settings = parentSettings, settings = parentSettings,
aggregate = Seq(camelSample, fsmSample, helloSample, helloKernelSample, remoteSample, persistenceSample, clusterSample, multiNodeSample, osgiDiningHakkersSample) aggregate = Seq(camelSample, fsmSample, mainSampleJava, mainSampleScala, helloKernelSample, remoteSample, persistenceSample, clusterSample, multiNodeSample, osgiDiningHakkersSample)
) )
lazy val camelSample = Project( lazy val camelSample = Project(
@ -463,9 +463,16 @@ object AkkaBuild extends Build {
settings = sampleSettings settings = sampleSettings
) )
lazy val helloSample = Project( lazy val mainSampleJava = Project(
id = "akka-sample-hello", id = "akka-sample-main-java",
base = file("akka-samples/akka-sample-hello"), base = file("akka-samples/akka-sample-main-java"),
dependencies = Seq(actor),
settings = sampleSettings
)
lazy val mainSampleScala = Project(
id = "akka-sample-main-scala",
base = file("akka-samples/akka-sample-main-scala"),
dependencies = Seq(actor), dependencies = Seq(actor),
settings = sampleSettings settings = sampleSettings
) )