How to deploy on anynines using Typesafe Activator

TL;DRTypesafe-Activator

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.

Typesafe Activator is cool and here’s why

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.

Prerequisites

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.

Creating the basis

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) minimal-akka-java-seed
2) minimal-akka-scala-seed
3) minimal-java
4) minimal-scala
5) play-java
6) play-scala
(hit tab to see a list of all templates)
> 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.

Modifying the application setup

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.

Modifying the code

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:

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);
  }
}

Now modify the onReceive method of PongActor as follows:

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);
  }
}

Feel free to test the app locally by executing

> run

inside Activator.

It’s alive! Push it to the cloud

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

       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

Well done!

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 :)

Leave a Reply

Your email address will not be published. Required fields are marked *

*