Jens Breuer
Published at 29.06.2015
A short version for the impatient.
I assume you’ve got git, Typesafe Activator and an anynines user account.
Clone the source:
$ git clone git@github.com:anynines/a9s-java-pingpong.git
Skip to “Push it to the cloud” below.
I know Java since the mid-nineties and to be honest it’s my favorite weapon of choice when it comes to coding.
I’ve done much web development in the past and when I heard about Play! Framework many years ago I was pretty excited. Take the philosophy of Ruby on Rails adopt it to Java and you’ve got Play. Play evolved over the years and is now wrapped inside Typesafe Activator. In fact, I stumbled upon Activator because of Play. Activator can do way more than I use it for but it lets me get things done quickly.
Lately I got to know about anynines and one of the first things I wanted to do was to deploy a Java application to anynines. Nothing fancy, it wasn’t even a web app – just a kind of “Hello World” app, but it serves well to show how to combine Activator and anynines.
To follow my steps you’ll need a working JDK on your machine as well as Typesafe Activator, the cf CLI and a anynines user account.
Let’s start with setting up a fresh Activator project first:
$ activator new
Fetching the latest list of templates...
Browse the list of templates: https://typesafe.com/activator/templates Choose from these featured templates or enter a template name:
1 Enter a name for your application (just press enter for 'minimal-akka-java-seed') a9s-java-pingpong OK, application "a9s-java-pingpong" is being created using the "minimal-akka-java-seed" template.
Now cd in the freshly created directory and run:
$ activator
You’re now inside the Activator shell where you may issue commands.
I usually use Eclipse to do Java coding, however there is an Eclipse Plugin for SBT that we can use to have SBT (yes, we are in Scala-land by now :) generate Eclipse project files from our Activator project.
Additionally, we’ll need a plugin for SBT that allows us to package our final app in a way that is suitable for the cf CLI in order to deploy our app to anynines. To accomplish that task we’ll use the SBT Native Packager plugin.
Modify “project/plugins.sbt” (create the file if it doesn’t exist) as follows:
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.0.0")
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "3.0.0")
Append the following lines to “build.sbt”:
lazy val root = (project in file(".")).enablePlugins(JavaAppPackaging)
EclipseKeys.withBundledScalaContainers := false
Restart Activator (STRG+C) for the changes to take effect.
Fire up your favorite code editor or let SBT generate Eclipse project files while you make yourself coffee. From within Activator run:
> eclipse
Now you may use Eclipse’s “import existing project” function.
We want our Actors to constantly play Ping-Pong, so we’ll remove the counter in PingActor and modify the onReceive method as follows:
[java light=”true”]public void onReceive(Object message) throws Exception {
if (message instanceof Initialize) {
log.info("In PingActor – starting ping-pong");
pongActor.tell(new PingMessage("ping"), getSelf());
} else if (message instanceof PongActor.PongMessage) {
PongActor.PongMessage pong =
(PongActor.PongMessage) message;
log.info("In PingActor – received message: {}",
pong.getText());
// schedule ping to be send in 1 second
getContext()
.system()
.scheduler()
.scheduleOnce(Duration.create(1, SECONDS),
getSender(),
new PingMessage("ping"),
getContext().dispatcher(),
getSelf());
} else {
unhandled(message);
}
}
[/java]
Now modify the onReceive method of PongActor as follows:
[java light=”true”]
public void onReceive(Object message) throws Exception {
if (message instanceof PingActor.PingMessage) {
PingActor.PingMessage ping = (PingActor.PingMessage) message;
log.info("In PongActor – received message: {}",
ping.getText());
// schedule pong to be send in 1 second
getContext()
.system()
.scheduler()
.scheduleOnce(Duration.create(1, SECONDS),
getSender(),
new PongMessage("pong"),
getContext().dispatcher(),
getSelf());
} else {
unhandled(message);
}
}
[/java]
Feel free to test the app locally by executing
> run
inside Activator.
Since we have a working application now, let’s run it in the cloud. We’ll use the SBT Native Packager plugin to have everything we need packed for a successful deploy. Open Activator and run:
> universal:packageBin
Relative to the root directory of the project we get a ZIPped archive:
target/universal/a9s-java-pingpong-1.0.zip
Make sure that the target for the cf CLI is correct:
$ cf api https://api.de.a9s.eu
Then login using your credentials selecting ORGs and spaces as you like:
$ cf login
Now let’s push our application to anynines:
$ cf push pingpong --no-route \ -b https://github.com/cloudfoundry/java-buildpack.git \ -p target/universal/a9s-java-pingpong-1.0.zip
Since we do not provide a HTTP interface (remember: our application does not interact with the outside world), we tell cf with the no-route option to avoid route creation (and with that the corresponding health check).
Voila! Let’s check if our application is running:
$ cf app pingpong Showing health and status for app pingpong in org ***_*** / space test as ***@***... OK
requested state: started instances: 1/1 usage: 256M x 1 instances urls: package uploaded: Mon May 4 13:57:33 +0000 2015
Code Example
1 state since cpu memory disk details
#0 running 2015-05-04 03:58:13 PM 1.4% 148.5M of 256M 125.3M of 1G
Looks good! Now watch the Actors play Ping-Pong:
$ cf logs pingpong
You’ve just successfully deployed a plain Java application (using main(.) as PEP) to anynines. Plus, we’ve used Akka to have two Actors play Ping-Pong.
With that knowledge we are ready to start building asynchronous messaging applications that are heavily scalable using Java, Akka and anynines. But that’s for the next episode – as for now, stay tuned to our twitter and shoot me an email if you’d like to talk about Scala-land :)
© anynines GmbH 2024
Products & Services
© anynines GmbH 2024