rewrite quickstart page, #22900
This commit is contained in:
parent
4cb9c2436f
commit
68aeba1cb7
4 changed files with 13 additions and 200 deletions
|
|
@ -1,136 +1,26 @@
|
|||
# Quickstart
|
||||
|
||||
After all this introduction, we are ready to build our first actor system. We will do so in three chapters.
|
||||
After all this introduction, we are ready to build our first actor system. We will do so in five chapters.
|
||||
This first chapter will help you to set up your project, tools and have a simple "Hello World" demo running.
|
||||
We will keep this section to a bare minimum and then extend the sample application in the next chapter. Finally, we review
|
||||
what we have learned in the third chapter, looking in detail how the pieces work and fit together.
|
||||
We will keep this section to a bare minimum and then extend the sample application in the next chapter.
|
||||
|
||||
> Our goal in this chapter is to set up a working environment for you, create an application that starts up and stops
|
||||
an ActorSystem and create an actor which we will test.
|
||||
an ActorSystem and create an actor which we will run and test.
|
||||
|
||||
Akka requires that you have [Java 8](http://www.oracle.com/technetwork/java/javase/downloads/index.html) or
|
||||
later installed on your machine.
|
||||
|
||||
As the very first thing, we need to make sure that we can compile our project and have a working IDE setup to be
|
||||
able to edit code comfortably. Depending on preference for build tool and IDE there are multiple paths that can
|
||||
be followed.
|
||||
able to edit code comfortably.
|
||||
|
||||
## Setting Up the Build
|
||||
**FIXME all links to hello-akka shall be replaced by akka-scala-seed / akka-java-seed**
|
||||
|
||||
Depending on the choice of build tool, we need to set up the layout for our project and tell the build tool about our
|
||||
dependencies (libraries that we want to use). There are common things to care for independently of our choice
|
||||
of build tool:
|
||||
The easiest way is to use the @scala[`akka-scala-seed` in [Get started with Lightbend technologies](http://dev.lightbend.com/start/?group=akka&project=hello-akka)] @java[`akka-java-seed` in [Get started with Lightbend technologies](http://dev.lightbend.com/start/?group=akka&project=hello-akka)]
|
||||
|
||||
* Declare `akka-actor` as a dependency. This is the core library of Akka, the one we are now learning
|
||||
* Declare `akka-testkit` as a dependency. This is a toolkit for testing Akka applications. Without this
|
||||
dependency we will have a hard time testing actors.
|
||||
* **Use the latest Akka version for new projects (unless there are additional constraints)!**
|
||||
* **Don’t mix Akka versions! You are free to use any Akka version in your project, but you must use
|
||||
that version for all Akka core projects** In this sample it means that `akka-actor` and `akka-testkit` should
|
||||
always be the same version.
|
||||
1. Enter Project Name and create the project from the @scala[[akka-scala-seed](http://dev.lightbend.com/start/?group=akka&project=hello-akka)] @scala[[akka-java-seed](http://dev.lightbend.com/start/?group=akka&project=hello-akka)] page.
|
||||
|
||||
### sbt
|
||||
1. Unzip the zip file and rename the directory to your preference.
|
||||
|
||||
If the choice is to use [sbt](http://www.scala-sbt.org/), the first step is to set up the directory structure for the project. sbt follows the
|
||||
directory layout standard of Maven. Usually, this means to start with the following directories and files:
|
||||
1. Read the @scala[[Guide](http://developer.lightbend.com/guides/hello-akka/)] @java[[Guide](http://developer.lightbend.com/guides/hello-akka/)] for this example project. It describes the example, the basic concepts of actors and how to run the "Hello World" application. ** **FIXME the Guide is in progress [here](https://github.com/akka/akka-scala-seed.g8/pull/4/files#diff-179702d743b88d85b3971cba561e6ace)**.
|
||||
|
||||
* `/src`
|
||||
* `/main` (this is where main, production classes live)
|
||||
* `/scala` (this is where Scala classes live)
|
||||
* `/java` (this is where Java classes live if Java is to be used)
|
||||
* `/resources` (this is where non-source files live which are required on the classpath.
|
||||
A typical example is application.conf which contains the configuration for the application.
|
||||
We will cover this in detail in CONFIG-SECTION)
|
||||
* `/test`
|
||||
* `/scala` (this is where Scala test and test helper classes live)
|
||||
* `/java` (this is where Java test and test helper classes live if Java is to be used)
|
||||
* `/resources` (this is where non-source files live which are required on the classpath to run tests.
|
||||
Typically this contains an application.conf that overrides the default configuration for tests. We will
|
||||
cover this in detail in CONFIG-SECTION)
|
||||
* `project`
|
||||
* `build.properties` ()
|
||||
* `build.sbt`
|
||||
|
||||
For example, if there is a Scala class `TestClass` in package `com.example.foo` then it should go in
|
||||
`/src/main/scala/com/example/foo/TestClass.scala`.
|
||||
|
||||
The file `build.sbt` contains the necessary information for sbt about the project metadata and dependencies.
|
||||
For our sample project, this file should contain the following:
|
||||
|
||||
@@@vars
|
||||
```scala
|
||||
// build.sbt
|
||||
|
||||
name := "intro-akka"
|
||||
organization := "intro-akka.organization"
|
||||
version := "0.1-SNAPSHOT"
|
||||
|
||||
scalaVersion := $scala.version$
|
||||
val AkkaVersion = $akka.version$
|
||||
|
||||
libraryDependencies += "com.typesafe.akka" %% "akka-actor" % AkkaVersion
|
||||
libraryDependencies += "com.typesafe.akka" %% "akka-testkit" % AkkaVersion % "test"
|
||||
```
|
||||
@@@
|
||||
|
||||
This simple file sets up first the project metadata ( _name_ and _organization_; we just picked a sample one here).
|
||||
Thereafter we set up the version of the Scala compiler we use, then set a variable with the Akka version we intend to
|
||||
use. Always strive to use the latest version.
|
||||
|
||||
As the last step, we add two dependencies, `akka-actor` and `akka-testkit`. Note that we used the `AkkaVersion`
|
||||
variable for both dependencies, ensuring that versions are not accidentally mixed and kept in sync when upgrading.
|
||||
|
||||
Finally, check that everything works by running `sbt update` from the base directory of your project
|
||||
(where the `build.sbt` file is).
|
||||
|
||||
## Setting up Your IDE
|
||||
|
||||
If [IDEA](https://www.jetbrains.com/idea/) is the choice of IDE, it has flexible means to import project either manually created by one of the
|
||||
previous steps from @ref:[setting up the build](#setting-up-the-build), or to let IDEA create it for you. Depending on your build tool,
|
||||
there are detailed steps in the IDEA documentation:
|
||||
|
||||
sbt
|
||||
: [https://www.jetbrains.com/help/idea/2016.2/getting-started-with-sbt.html](https://www.jetbrains.com/help/idea/2016.2/getting-started-with-sbt.html)
|
||||
|
||||
## Building the First Application
|
||||
|
||||
Akka applications are simply Scala or Java applications. To get an actor system up and running there is no need to set up any container, application server, etc. Instead, all that is needed is a class with a proper `main` method that starts and stops an actor
|
||||
system. The pieces of the puzzle that we need to put together are: What is an actor system and why do I need one?
|
||||
How can we start and stop it? Why do we need to stop it?
|
||||
|
||||
In Akka, actors belong to actor systems, which are instances of the type `ActorSystem`. This class acts as a
|
||||
resource container which holds among others:
|
||||
|
||||
* Configuration shared by all actors in that system.
|
||||
* A pool of threads that will execute actors that are ready to process messages.
|
||||
* A dispatcher mechanism that dynamically assigns actors to threads of the pool.
|
||||
* A scheduler used for timer-related tasks.
|
||||
|
||||
The `ActorSystem` manages its actors and runs them in the background on its encapsulated thread pool.
|
||||
This means that is must be explicitly shut down, otherwise, these threads keep running and the JVM does
|
||||
not exit (by default threads created by ActorSystem are not daemon threads; see the JDK documentation on
|
||||
more details on [daemon or non-daemon threads](https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html)).
|
||||
The usual pattern is to have your system set up to stop on external signal (i.e. user pressing ENTER in the console).
|
||||
|
||||
Once there is an `ActorSystem` we can populate it with actors. This is done by using the `actorOf` method. The `actorOf` method expects a `Props` instance and the name of the actor to be created. You can think of the `Props` as a configuration value for what actor to create and how it should be created. Creating an actor with the `actorOf` method will return an `ActorRef` instance. Think of the `ActorRef` as a unique address with which it is possible to message the actor instance. The `ActorRef` object contains a few methods with which you can send messages to the actor instance. One of them is called `tell`, or in the Scala case simply `!` (bang), and this method is used in the example here below. Calling the `!` method is an asynchronous operation and it instructs Akka to send a message to the actor instance that is uniquely identified by the actor reference.
|
||||
|
||||
Scala
|
||||
: @@snip [HelloWorldApp.scala]($code$/scala/quickstart/HelloWorldApp.scala) { #create-send }
|
||||
|
||||
Java
|
||||
: @@snip [HelloWorldMain.java]($code$/java/jdocs/quickstart/HelloWorldMain.java) { #create-send }
|
||||
|
||||
Before we can create any actor in the actor system we must define one first. Luckily, creating actors in Akka is quite simple! Just have your actor class extend @scala[`Actor`] @java[`AbstractActor`] and override the method @scala[`receive: Receive`] @java[`public Receive createReceive()`] and you are good to go. As for our `HelloWorldActor` class, it extends @scala[`Actor`] @java[`AbstractActor`] and overrides the @scala[`receive`] @java[`createReceive`] method as per the requirement. Our implementation of the @scala[`receive`] @java[`createReceive`] method expects messages of type `String`. For every `String` message it receives it will print "Hello " and the value of the `String`. Since the message we send in the main class is "World" we expect the string "Hello World" to be printed when running the application.
|
||||
|
||||
Scala
|
||||
: @@snip [HelloWorldApp.scala]($code$/scala/quickstart/HelloWorldApp.scala) { #actor-impl }
|
||||
|
||||
Java
|
||||
: @@snip [HelloWorldActor.java]($code$/java/jdocs/quickstart/HelloWorldActor.java) { }
|
||||
|
||||
Here is the full example:
|
||||
|
||||
Scala
|
||||
: @@snip [HelloWorldApp.scala]($code$/scala/quickstart/HelloWorldApp.scala) { #full-example }
|
||||
|
||||
Java
|
||||
: @@snip [HelloWorldMain.java]($code$/java/jdocs/quickstart/HelloWorldMain.java) { #full-example }
|
||||
|
||||
Now that you have seen the basics of an Akka application it is time to dive deeper.
|
||||
After that you can go back here and you are ready to dive deeper.
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
package jdocs.quickstart;
|
||||
|
||||
import akka.actor.AbstractActor;
|
||||
import akka.actor.AbstractActor.Receive;
|
||||
|
||||
//#actor-impl
|
||||
public class HelloWorldActor extends AbstractActor {
|
||||
public Receive createReceive() {
|
||||
return receiveBuilder()
|
||||
.match(String.class, msg -> {
|
||||
System.out.println("Hello " + msg);
|
||||
})
|
||||
.build();
|
||||
}
|
||||
}
|
||||
//#actor-impl
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
//#full-example
|
||||
package jdocs.quickstart;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import akka.actor.ActorRef;
|
||||
import akka.actor.Props;
|
||||
import akka.actor.ActorSystem;
|
||||
|
||||
public class HelloWorldMain {
|
||||
public static void main(String[] args) throws IOException {
|
||||
//#create-send
|
||||
ActorSystem system = ActorSystem.create("hello-world-actor-system");
|
||||
try {
|
||||
// Create hello world actor
|
||||
ActorRef helloWorldActor = system.actorOf(Props.create(HelloWorldActor.class), "HelloWorldActor");
|
||||
// Send message to actor
|
||||
helloWorldActor.tell("World", ActorRef.noSender());
|
||||
|
||||
System.out.println("Press ENTER to exit the system");
|
||||
System.in.read();
|
||||
} finally {
|
||||
system.terminate();
|
||||
}
|
||||
//#create-send
|
||||
}
|
||||
}
|
||||
|
||||
//#full-example
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
//#full-example
|
||||
package quickstart
|
||||
|
||||
import akka.actor.{ Actor, ActorRef, Props, ActorSystem }
|
||||
import scala.io.StdIn
|
||||
|
||||
object HelloWorldApp {
|
||||
def main(args: Array[String]): Unit = {
|
||||
//#create-send
|
||||
val system = ActorSystem("hello-world-actor-system")
|
||||
try {
|
||||
// Create hello world actor
|
||||
val helloWorldActor: ActorRef = system.actorOf(Props[HelloWorldActor], "HelloWorldActor")
|
||||
// Send message to actor
|
||||
helloWorldActor ! "World"
|
||||
// Exit the system after ENTER is pressed
|
||||
StdIn.readLine()
|
||||
} finally {
|
||||
system.terminate()
|
||||
}
|
||||
//#create-send
|
||||
}
|
||||
}
|
||||
|
||||
//#actor-impl
|
||||
class HelloWorldActor extends Actor {
|
||||
def receive = {
|
||||
case msg: String => println(s"Hello $msg")
|
||||
}
|
||||
}
|
||||
//#actor-impl
|
||||
//#full-example
|
||||
Loading…
Add table
Add a link
Reference in a new issue