Creating an RxJava Observable from an Akka Actor

Recently I found myself wondering about the ways of combining two awesome libraries: Akka and RxJava. The most straightforward use case for me was about converting a stream of messages received by an Actor into an Observable.

I’ll quickly write down how that works, and maybe this will be the start of a new little series of blogs. And maybe, I’ll learn something along the way about how to best create an Akka module for RxJava, something I’d love to do…

But I’ll start very very small. This is not going to go into any kind of error handling, or explore the Akka Event Bus, for example. — All this will have to wait for later.

First, I’ll need a small build.sbt that’s mostly there to import the two dependencies for me:

organization := "de.johoop",
name := "akka-rxjava",
version := "1.0.0-SNAPSHOT",
scalaVersion := "2.10.3",
scalacOptions ++= Seq("-deprecation", "-language:_"))
libraryDependencies ++= Seq(
  "com.typesafe.akka" %% "akka-actor" % "2.2.1",
  "com.netflix.rxjava" % "rxjava-core" % "0.14.5",
  "com.netflix.rxjava" % "rxjava-scala" % "0.14.5"))

Next, I’ll need to define a simple message…

sealed trait Message
case class Hello(text: String) extends Message

…and a basic actor that receives them:

import akka.actor._

class ObservableActor extends Actor with ActorLogging {
  def receive = {
    case message: Message =>
      log debug s"incoming: $message"
  }
}

Now let’s add a simple Main and try it out:

object Main extends App {
  val system = ActorSystem("client")

  val receiver = system actorOf (Props[ObservableActor], "rcv")
  Seq("hello", "world", "again", "not anymore") foreach { msg => 
    receiver ! Hello(msg)
  }

  system.shutdown
}

Up to now, this is pure Akka, and of course it works as expected. Now, for making an Observable out of this, I’ll need a mechanism for subscribing and unsubscribing. For subscribing, I want to be able to specify a callback onNext that will be called each time a message is received.

This means that I need a few more messages:

sealed trait SubUnsub extends Message
case class Subscribe(onNext: Message => Unit) extends SubUnsub
case object Unsubscribe extends SubUnsub

My actor has to handle these new messages, of course. I’ll use the Become mechanism for this in order to avoid any kind of mutable state. And very important: I want to call the new callback upon receiving messages instead of just logging them. All this means that the new version of the actor looks like this:

class ObservableActor extends Actor with ActorLogging {
  def receive = {
    case Subscribe(onNext) =>
      log debug "subscribe"
      context become subscribed(onNext)
  }

  def subscribed(onNext: Message => Unit): Actor.Receive = {
    case Unsubscribe =>
      log debug "unsubscribe"
      context become receive

    case message: Message =>
      log debug s"incoming: $message"
      onNext(message)
  }
}

At last, I’m prepared to create an Observable. This is the step where the “magic” happens. I’ll add a small utility function for this:

import rx.lang.scala._ // the additional import for RxJava

def observableFromActor(actor: ActorRef): Observable[Message] = 
  Observable { observer =>
    actor ! Subscribe(observer onNext)
    new Subscription { 
      override def unsubscribe: Unit = actor ! Unsubscribe 
    }
  }

What happens here is that in order to create an Observable, I need a function that takes an Observer (which provides the required callback(s) and wants to get notified about messages) and returns a Subscription (for unsubscribing).

On subscription, we send the Subscribe message to the actor, telling it about the callback. And on unsubscription, we send the Unsubscribe message. That’s all there is to it.

Let’s extend our Main object to try it out:

val subscription = 
  observableFromActor(receiver) 
    .take(3)
    .subscribe(msg => println(s"received: $msg"))

Seq("hello", "world", "again", "not anymore") foreach { msg => 
  receiver ! Hello(msg)
}

subscription.unsubscribe

Aaaand it still does it’s thing. I’m good. For now.

In conclusion, I have to say that this was surprisingly easy. Of course, maybe that’s just because I left out all the more interesting things…

Thanks for reading! :-)

For reference, here’s the complete code of the example:

import akka.actor._
import rx.lang.scala._

sealed trait Message
case class Hello(text: String) extends Message

sealed trait SubUnsub extends Message
case class Subscribe(onNext: Message => Unit) extends SubUnsub
case object Unsubscribe extends SubUnsub

object Main extends App {
  val system = ActorSystem("client")
  val receiver = system actorOf (Props[ObservableActor], "rcv")

  val subscription =
    observableFromActor(receiver)
      .take(3)
      .subscribe(msg => println(s"received: $msg"))

  Seq("hello", "world", "again", "not anymore") foreach { msg =>
    receiver ! Hello(msg)
  }
  subscription.unsubscribe
  system.shutdown

  def observableFromActor(actor: ActorRef): Observable[Message] =
    Observable { observer =>
      actor ! Subscribe(observer onNext)
      new Subscription {
        override def unsubscribe: Unit = actor ! Unsubscribe
      }
    }
}

class ObservableActor extends Actor with ActorLogging {
  def receive = {
    case Subscribe(onNext) =>
      log debug "subscribe"
      context become subscribed(onNext)
  }

  def subscribed(onNext: Message => Unit): Actor.Receive = {
    case Unsubscribe =>
      log debug "unsubscribe"
      context become receive

    case message: Message =>
      log debug s"incoming: $message"
      onNext(message)
  }
}
Posted in Scala at October 22nd, 2013. 1 Comment.

Getting Started with ScalaFX and resizable UIs

When I was a school kid oh so long ago, the most permanent subject of my programming hobby was an AI for “Connect Four” (besides lots of genetic algorithm and neural network stuff, sigh). I remember very well the thousands of lines of code and the weeks I spent trying to get that right (using Turbo Pascal), and to get it to be able to beat me at the game. However, I got better at the game faster than my AI, I’m afraid.

Today I know that “Connect Four” is a solved problem. Still, I think it’s a nice programming playground. And as I wanted to find out how far I’ve come with my development skills since I was a school kid, I decided to ignore that research paper and use “Connect Four” as a playground for trying out Akka and ScalaFX for a bit over the holidays – if you want to skip ahead, you’ll find the results at Bitbucket.

So, here’s a blog about how I started out with ScalaFX in  that little project.

The first steps to getting started with ScalaFX were not immediately clear to me. There’s a tutorial about how to get started with ScalaFX within Eclipse alright, but for using it from SBT, I fortunately remembered a Herbstcampus talk by @phdoerfler. You can find the (German) slides and an SBT build file here. Turns out it’s quite easy.

The first thing you need to know about ScalaFX is that it’s unfortunately not published anywhere. That means that you have to publish it locally in order to be able to use it as a library.

Doing this means installing Mercurial if you haven’t got it already, and then cloning the ScalaFX repository:

hg clone https://code.google.com/p/scalafx/

Next, you have to package and publish ScalaFX. If you’ve got git installed, too, then this should do the trick:

sbt publish-local

However, if you don’t have git installed, you have to remove the project/plugins/project/PluginBuild.scala file first, which references an sbt plugin (used for the test target) cloned from git. This plugin is not really required for locally publishing ScalaFX, anyway.

Now you’re set for referencing ScalaFX in your own SBT build – just add ScalaFX as a library dependency, and also add the JavaFX runtime (coming from your local Java 7 installation, if it’s up-to-date as it should be) as a dependency:

libraryDependencies += "org.scalafx" % "scalafx" % "1.0-SNAPSHOT"

unmanagedJars in Compile += Attributed.blank(
    file(scala.util.Properties.javaHome) / "lib" / "jfxrt.jar")

fork in run := true

As you notice, I have also told the run command to fork in order to avoid “UnsatisfiedLinkError“s due to various classloader “magics”…

On to coding: For my Connect Four board, I wanted to start with a pane within a resizable window where I just do the layout myself, basically drawing the board with the help of ScalaFX shapes instead of using Graphics2D. At first I thought that that would be easy, but then I spend a lot of time on one single detail: Namely, how to get the ScalaFX UI to resize with the window. Incidentally, this is what spawned this blog post.

My main class started out quite simple, as any ScalaFX application does:

import scalafx.Includes._
import scalafx.application.JFXApp
import scalafx.stage.Stage

object Main extends JFXApp {
  stage = new Stage {
    title = "Akka Connect Four"
    width = 800
    height = 600
  }
}

This sets the stage, and that’s all. – Next, you have to add the scene graph to the stage. Normally, you’d do this by simply adding scene = new Scene { ... } to the stage. But that’s exactly what broke my neck when trying to make the scene resize together with the window. And the reason for this is that ScalaFX internally puts a JavaFX “group” as the root of the scene here, instead of a single component.

Using a single component as root for the ScalaFX scene graph unfortunately doesn’t seem to be well supported by ScalaFX. The only way I was able to make it work is by doing it like this, directly creating a scene via JavaFX:

import scalafx.Includes._
import scalafx.application.JFXApp
import scalafx.stage.Stage
import scalafx.scene.Scene
import scalafx.scene.layout.BorderPane

object Main extends JFXApp {
  stage = new Stage {
    title = "Akka Connect Four"
    width = 800
    height = 600

    scene = new Scene(new javafx.scene.Scene(root))
  }

  lazy val root = new BorderPane {}
}

I’m using a BorderPane here as a container so that I can arrange additional stuff around my Connect Four board later on.

Next, let’s add the basic board rectangle to the center of the root pane.

import scalafx.Includes._
import scalafx.application.JFXApp
import scalafx.stage.Stage
import scalafx.scene.Scene
import scalafx.scene.layout.{ Pane, BorderPane }
import scalafx.scene.shape.Rectangle
import javafx.scene.paint.{ Color => JFXColor }

object Main extends JFXApp {
  stage = new Stage {
    title = "Akka Connect Four"
    width = 800
    height = 600

    scene = new Scene(new javafx.scene.Scene(root))
  }

  lazy val root = new BorderPane {
    center = gamePane
  }

  lazy val gamePane: Pane = new Pane {
    content = showBoard(784.0, 562.0)
  }

  def showBoard(paneWidth: Double, paneHeight: Double) = {
    val offX = 50.0
    val offY = 50.0
    val boardWidth = paneWidth - offX * 2
    val boardHeight = paneHeight - offY * 2
    
    new Rectangle {
      x = offX
      y = offY
      width = boardWidth
      height = boardHeight
      fill = JFXColor.DEEPSKYBLUE
    }
  }
}

This way, we get a nice centered blue rectangle (I won’t add more details to it for the purpose of this blog post). However, you may have already noticed that the board still doesn’t resize itself when you resize the window. At least the pane itself does resize itself thanks to our trick with the root component above (you can check that by setting the background color, for example, or by using Scenic View – which is an awesome tool for debugging JavaFX UIs, by the way).

In order to get a resizing board, we still have to bind the width and height of the game pane to redrawing our board. Now, if there’s something that’s really awesome in ScalaFX, then it’s how simple this can be done, using “bind expressions”. In our case, we just want to show an updated board every time the width or height of the window changes. Therefore, we want to set width.onChange() and height.onChange().

Here’s what I did:

import scalafx.Includes._
import scalafx.application.JFXApp
import scalafx.stage.Stage
import scalafx.scene.Scene
import scalafx.scene.layout.{ Pane, BorderPane }
import scalafx.scene.shape.Rectangle
import javafx.scene.paint.{ Color => JFXColor }

object Main extends JFXApp {
  stage = new Stage {
    title = "Akka Connect Four"
    width = 800
    height = 600

    scene = new Scene(new javafx.scene.Scene(root))

    width onChange show
    height onChange show
  }

  lazy val root = new BorderPane {
    center = gamePane
  }

  lazy val gamePane: Pane = new Pane {
    content = showBoard(784.0, 562.0)
  }

  def show: Unit = {
    gamePane.content = showBoard(gamePane.width.get, gamePane.height.get)
  }


  def showBoard(paneWidth: Double, paneHeight: Double) = {
    val offX = 50.0
    val offY = 50.0
    val boardWidth = paneWidth - offX * 2
    val boardHeight = paneHeight - offY * 2
    
    new Rectangle {
      x = offX
      y = offY
      width = boardWidth
      height = boardHeight
      fill = JFXColor.DEEPSKYBLUE
    }
  }
}

And that’s it already: A resizable game board for my Connect Four UI.

And as I’m still a bloody ScalaFX newbie: Should you know a way to do any of the above easier, please write a comment below!

You can also check out the source code of the Connect Four application at BitBucket. – That said, it’s not complete in any way (no parallelism at all yet, no permanent brain, nearly completely unoptimized for performance, for example).

However, I got it to being able to play on par with me within a few days of eating christmas cookies and casually hacking, and that’s awesome and depressing at the same time! :)

Posted in Scala at January 3rd, 2013. 3 Comments.

Linked Lists in Datomic

As my last contact with Prolog was over ten years ago, I think it’s time for some fun with Datomic and Datalog. In order to learn to know Datomic better, I will attempt to implement linked lists as a Datomic data structure.

First, I need a database “schema”, which in Datomic means that I have to define a few attributes. I’ll define one :content/name (as a string) for naming my list items, and also the attributes for the list data structure itself, namely :linkedList/head and :linkedList/tail (both are refs):

[{:db/id #db/id[:db.part/db], 
  :db/ident :content/name, 
  :db/valueType :db.type/string, 
  :db/cardinality :db.cardinality/one, 
  :db/doc "Simple demo list content.", 
  :db.install/_attribute :db.part/db}
  
 {:db/id #db/id[:db.part/db], 
  :db/ident :linkedList/head, 
  :db/valueType :db.type/ref, 
  :db/cardinality :db.cardinality/one, 
  :db/doc "The head of a linked list.", 
  :db.install/_attribute :db.part/db}
  
 {:db/id #db/id[:db.part/db], 
  :db/ident :linkedList/tail, 
  :db/valueType :db.type/ref, 
  :db/cardinality :db.cardinality/one, 
  :db/doc "The tail of a linked list. Should point to a linked list.", 
  :db.install/_attribute :db.part/db}]

Next, I’ll create some sample data. I’ll define a simple list (A, B, C, D):

[{:db/id #db/id[:db.part/user -1], :content/name "A"}
 {:db/id #db/id[:db.part/user -2], :content/name "B"}
 {:db/id #db/id[:db.part/user -3], :content/name "C"}
 {:db/id #db/id[:db.part/user -4], :content/name "D"}

 {:db/id #db/id[:db.part/user -5], 
  :linkedList/head #db/id[:db.part/user -1], 
  :linkedList/tail #db/id[:db.part/user -6]}
  
 {:db/id #db/id[:db.part/user -6], 
  :linkedList/head #db/id[:db.part/user -2], 
  :linkedList/tail #db/id[:db.part/user -7]}
  
 {:db/id #db/id[:db.part/user -7], 
  :linkedList/head #db/id[:db.part/user -3], 
  :linkedList/tail #db/id[:db.part/user -8]}
  
 {:db/id #db/id[:db.part/user -8], 
  :linkedList/head #db/id[:db.part/user -4]}]

Now, for some queries. Let’s warm up a bit first.

Finding all contents (not by list):

[:find ?n :where [_ :content/name ?n]]

Finding the head of our list (knowing it starts with A):

[:find ?h :where [?h :linkedList/head ?c] [?c :content/name \"A\"]]

Next we need a rule that defines when two list items are linked. The first thing that comes to mind is that two items are linked when one is the head and the other is the (head of the) tail. So:

[[[linked ?h ?t] [?h :linkedList/tail ?t]]]

Now I can query for the list item linked to A, using this rule:

[:find ?n :in $ % :where 
  [?c :content/name ?n] 
  [?e :linkedList/head ?c] 
  [linked ?f ?e] 
  [?f :linkedList/head ?a] 
  [?a :content/name \"A\"]]

This will only return B, of course. To get the whole list, I’ll need a recursive rule. Now how does that work? – Let’s see:

[[[linked ?h ?t]
    [?h :linkedList/tail ?t]]
 [[linked ?h ?t] 
    [linked ?h ?x]
    [?x :linkedList/tail ?t]]]

So, I say that two list items are linked when they are directly linked, or when there is an intermediate list item that recursively is linked to one and directly linked to the other input item.

Now what happens when I run the query from before with the new rule(s)? – Hmmm, I get B, C and D, but am still missing the A itself.

How to include the A, too, so that I get the complete list contents? – I’ll have to again extend the rules. Two list items should also be viewed as linked when they are the same:

[[[linked ?h ?t]
    [?h :linkedList/head]
    [?t :linkedList/head]
    [(= ?h ?t)]]
 [[linked ?h ?t] 
    [linked ?h ?x]
    [?x :linkedList/tail ?t]]]

These rules view two items as linked when they both are list items (insofar as they have the :linkedList/head attribute), and they are equal. Or, as above, when the two items are linked via an intermediate item.

Finally, I get A, B, C and D as a result. Of course, if I query like this, I won’t get them ordered. If I need them ordered, I’ll have to simply query one after the other, iterating through the list ourselves…

So, that’s all for today’s finger exercises…

In my humble opinion, Datomic is the best kind of NoSQL database I ever happened upon. It’s visionary: I’d absolutely love to do away with mutability (like Datomic does) in all my current projects with database backends…

I’ve also started a little project to create an easy-to-use Scala API for Datomic. I’m not yet sure which direction this will take, however. See here.

Posted in Datomic at August 18th, 2012. 1 Comment.

First Steps with Akka Remoting

Initially, I was hopeful that setting up a simple client/server infrastructure with akka would be very easy and painless because

  • akka documentation is generally very well-written and comprehensive,
  • the API looks astonishingly simple.
  • There are some good code samples in the akka repository.

Sadly, this was not really the case. – Of course, part of the problem is my own stupidity, I guess. Anyway, here are the pitfalls I encountered, some of them more, some of them less trivial:

  • Don’t let the links to old documentation versions misguide you! – Always check that the websites you’re looking at are about the most current version of akka.
  • The client seems to require a full ActorSystem with remoting just for calling remote actors on the server.
  • The client ActorSystem has to bind to a different port than the server ActorSystem when running on the same box. Use different configuration sections or files.
  • If you try to look up a remote actor using a wrong akka url, you won’t get any kind of error message. It just won’t work at all.
  • If you call your remote actor serverActor and your remote actor system ServerSystem, and it’s running on localhost:2554, its url is akka://ServerSystem@localhost:2554/user/serverActor, not akka://ServerSystem@localhost:2554/serverActor
  • Unfortunately, sbt dist won’t copy any subproject libraries into the mikrokernel when the id and name of your sbt subprojects are not equal. Always use the name you set in your subproject settings (for example name := "akka-shared") for your subproject id (lazy val shared = Project(id = "akka-shared", ...)

Maybe this saves a few other akka beginners a bit of their time. I pushed the code to a playground Bitbucket repository. You’re invited to take a look. I’d be very happy about any kinds of hints or pointers to possible improvements, of course.

Still, I’d say that getting started here was comparatively easy when I think back to the fun times I had when first learning how to setup the Orion Application Server or JBoss back in the days…

Posted in Scala at August 8th, 2012. 3 Comments.

Learning F# via Robocode: Setup and First Steps

Usually, I do my work and fun in JVM-based languages like Scala or sometimes Clojure; however, I get this nagging feeling that I’m missing something if I don’t look at the world of .NET once in a while, too.

C# is boringly similar to Java, so let’s try out F# for a change.

I recently noticed that Robocode now supports .NET, too (via jni4net). Yay! Let’s check it out!

First, bootup Windows. Next: installation stuff. Ugh.

As there’s no Visual F# Express (what is Microsoft thinking? shouldn’t they push F# more?) I’ll have to install the “Visual Studio (Integrated) Shell”, and then F# itself.

Alright, now I’m ready to open Visual Studio and create a F# project. Nice.

Next, I have to install Robocode itself and the .NET plugin (both from here): First, call the Robocode JAR setup jar, then install the robocode.dotnet setup jar on top of the created Robocode directory. By the way, I’m loosely following the instructions in the awesome Robocode Wiki for these steps.

In the “New Project” wizard of Visual Studio, I select “F# Library”, as we want to create a class library, not an application. I call my project “SharpyTheFirst” (yeah, well). Up comes the editor. But I don’t have any reference to Robocode yet, so let’s create one.

From the wiki again: “You need to add a reference to the robocode.dll file located under the \libs folder of your home folder for Robocode”. Right, let’s do exactly that.

Also, let’s change the assembly name right now to conform to the Robocode conventions: Right-click the project, then under Properties, Application, set the assembly name (I set it to johofer.SharpyTheFirst_1.0).

We’re finally all set for some hackage.

I’ll create the johofer namespace, as it’s the convention to use one’s nick for Robocode robot namespaces, open the Robocode namespace for my perusal, and create a class inheriting from Robocode.Robot because that’s how simple Robocode robots work:

#light
namespace johofer

open Robocode

type SharpyTheFirst() = 
    inherit Robot()

This still displays an error because Robot seems to depend on System.Drawing, so let’s add System.Drawing to the dependencies, too.

Next, I have to find out how to override a method in F# (stuff you normally don’t need in functional languages). It seems I need the override keyword for this, and a “self identifier”. I’ll call the self identifier this. Then, I basically have to translate the C# robot initialization, main loop and event handling into F# syntax. You can marvel at my first attempt here:

Now that we have a robot with extremely basic functionality, let’s find out if it works… at all… – quickly build it in Visual Studio, and then, finally start up Robocode!

Alrighty. The wiki says that I have to add the path to my newly built assembly in the Robocode IDE under Options, Preferences, Development Options.

Now, I can start the battle. Is johofer available under packages? Yes, it is! Woot!

Let’s have a fight: johofer.SharpyTheFirst vs sample.Crazy! – And… SharpyTheFirst wins! Yay!

So, to recapitulate:

  • Installed F#: Check.
  • Installed Robocode: Check.
  • Learnt how to do the ugly OO/inheritance stuff in F#: Check.
  • Implemented basic robot: Check.
  • Won a fight: Check.

That’s all for now. I hope you’ll try it out!

Posted in .NET at August 5th, 2012. 2 Comments.

A simple SBT build for your Scalatron bot

Recently, the Scala world got richer again – we now have our own educational robot wars hacking environment: Scalatron.

Unfortunately, it’s not yet well documented or obvious how to set that environment up, except for a huuuge instructions document for IntelliJ IDEA. I mean, 13 pages?! – That just has to be doable in an easier way!

As I’m an Eclipse user and somewhat fluent with SBT, I thought I’d try to setup Scalatron with an SBT build. With the sbteclipse (and sbt-idea) plugins, I’ll then get the IDE setup for free.

So, let’s create a basic SBT build file. As I already suspect that I’ll need a build that’s a bit more complicated than a few lines of configuring standard settings, let’s start with a Build.scala file:

import sbt._
import Keys._

object Build extends Build {
  val bot = Project(
    id = "mybot", 
    base = file("."), 
    settings = Project.defaultSettings ++ botSettings)

  val botSettings = Seq[Setting[_]](
    organization := "de.johoop",
    name := "my-scalatron-bot",
    version := "1.0.0-SNAPSHOT",

    scalaVersion := "2.9.1",
    scalacOptions ++= Seq("-deprecation", "-unchecked"))
}

This simply initializes my bot project and adds a few standard Scala options I usually like to use.

Next, I want to add the dependency to the Scalatron jar file to the project. As Scalatron isn’t published anywhere, I’ll just create a lib directory and put the jar file from the Scalatron distribution in there.

Another basic thing that’s still missing from the build is the configuration of some kind of tests. I absolutely want to write tests against my bot’s functionality, as it’s very difficult to debug a bot during a running bot war. I’ll use Specs2 for that, of course, because it’s all kinds of genius. We’ll add the following lines to our botSettings:

      libraryDependencies ++= Seq(
        "org.specs2" %% "specs2" % "1.8.2" % "test",
        "org.pegdown" % "pegdown" % "1.0.2" % "test",
        "junit" % "junit" % "4.7" % "test"),
      
      testOptions := Seq(
      	Tests.Filter(_ == "de.johoop.scalatron.BotSpec"), 
      	Tests.Argument("html", "console")),

      testOptions <+= crossTarget map { ct =>
        Tests.Setup { () => 
          System.setProperty("specs2.outDir", 
              new File(ct, "specs2").getAbsolutePath)
        }
      },

The first few lines add all required dependencies: pegdown for the nice HTML reports, junit for running the tests from within Eclipse using JUnit.

Then I tell SBT to just execute my main test specification called BotSpec and ignore any sub specifications. And I tell it to create HTML reports, too, and where to put them.

I can now already hack and test my bot to my heart’s content. However, I can’t yet try it out in the Scalatron environment. Let’s do something about this. I need a way to start the Scalatron simulation, and I probably want to configure the directory where all the bots are kept (the enemy bots as well as my own).

For this, I first create two simple SBT keys and add them to the Build class:

  val botDirectory = SettingKey[File]("bot-directory")
  val play = TaskKey[Unit]("play")

The botDirectory setting will simply be initialized to where I want to keep the bots (in the botSettings sequence):

      botDirectory := file("bots"),

The play task will have the job to take my bot jar and deploy it into the bot directory, and then to start a (forked) Scalatron simulation. In order to be able to do this, it will require quite a few dependencies as inputs:

  • botDirectory: where the bots go,
  • name: in order to name my bot in the bot directory,
  • javaOptions: so that I can configure memory settings and the like for the simulation,
  • unmanagedClasspath in Compile: to retrieve the Scalatron.jar from and finally
  • Keys.`package` in Compile: to retrieve my bot’s jar from.

So, here we go (again, at this to the botSettings):

      play <<= (botDirectory, name, javaOptions, 
                unmanagedClasspath in Compile, 
                Keys.`package` in Compile) map { 
                  (bots, name, javaOptions, ucp, botJar) =>

        IO createDirectory (bots / name)
        IO copyFile (botJar, bots / name / "ScalatronBot.jar")

        val cmd = "java %s -cp %s scalatron.main.Main -plugins %s" format (
            javaOptions mkString " ",
            Seq(ucp.files.head, botJar).absString,
            bots.absolutePath)
        cmd run
      }

And that’s it!

I can now deploy my bot to the bot directory and run the simulation from within SBT just by typing play into the SBT console.

Except… except that I noticed that the simulation seems to use a lot of memory, so I added a java option for this:

  javaOptions += "-Xmx1g"

And also, the Eclipse project I generate via the sbteclipse plugin unfortunately warns me about two Scala runtimes (one generated by the plugin, one inside the Scalatron jar). I won’t do anything against this, hoping that we’ll soon get a clean published Scalatron jar that doesn’t automatically include the Scala runtime…

Here’s my complete build file as a gist.

Now go and create your own Scalatron bot! :)

Posted in Scala at March 31st, 2012. 4 Comments.

Accessing the Heroku REST API via Dispatch

Now that I have an extremely simple Heroku app up and running (see my previous post) and don’t know what to do with it, the logical next step for me was to check out Heroku’s REST API. :)

Ok, so first, let’s look up the REST API documentation…

… but wait, such an abstruse beast does not exist! – Instead, we get the Ruby sources of the Heroku REST client. That’s fine with me, except that I don’t speak Ruby so well. But never mind, this looks easy enough.

Let’s check out what to use as REST client API in Scala: Restlet, Jersey or something? – Nooo! Let’s use Dispatch. Dispatch wins the coolness competition hands down, if you ask me. You’ll see below, I hope.

Of course, I’ll use sbt for building my little project. We add the following two dependencies and are done with it:

libraryDependencies ++= Seq(
  "net.databinder" %% "dispatch-http" % "0.8.5",
  "net.databinder" %% "dispatch-lift-json" % "0.8.5")
}

Now let’s import all the good stuff:

import dispatch._
import liftjson.Js._

import net.liftweb.json._
import JsonParser._

I’m going to prepare a few helpers next, and then we’re ready to rumble:

implicit val formats = DefaultFormats

val http = new Http
private val user = "*my-heroku-user*"
private val password = "*my-heroku-password*"

val herokuApi = :/("api.heroku.com", 443).as(user, password)
val herokuHeaders = Map(
    "Accept" -> "application/json", 
    "X-Heroku-Api-Version" -> "2")

Next, we can login, for example. This will return our api key, mostly (I don’t know yet what it’s good for though, seeing all the basic authentication that’s going on in the Ruby client).

def login = {
  http(resource(herokuApi / "login")
    < < Map("username" -> user, "password" -> password) 
    ># (_.extract[User]) )
}

def resource(request: Request) = 
  request.secure <: < herokuHeaders

(The "< <" and "<: <" above should really be "<<" and "<:<", don't ask me why WordPress puts in a space each time I save this post)

Wait, what's User? I have to define that before the above will work. It's just a simple case class which will be filled by Lift-JSON. And when I'm already at it, I'll define the case class for the next request here, too:

case class User(
    email: String, 
    api_key: String, 
    verified_at: Option[String])

case class HerokuApp(
    id: Int,
    name: String, 
    stack: Option[String], 
    requested_stack: Option[String],
    slug_size: Int, 
    repo_size: Int,
    dynos: Int,
    workers: Int,      
    created_at: String,
    create_status: String,
    repo_migrate_status: String)

Now I can call login and will receive something like this:
User(*my-heroku-user*,*my-api-key*,None)

This is fun!

Let's use the above HerokuApp case class to request our current Heroku apps:

def apps = http(resource(herokuApi / "apps") 
    ># (_.children map (_.extract[HerokuApp])))

Uhm... - yup, that's all there is to it. This returns a convenient list of apps I have running on Heroku:
List(HerokuApp(*my-id*,*my-app-name*,Some(cedar),None,*large-number-1*,*large-number-2*,0,0,2011/10/10 11:52:03 -0700,complete,complete))

This is great, isn't it? - I at least had no idea that it would turn out to be so very easy to connect to Heroku from Scala.

I still don't know what to put up on Heroku, though...

Posted in Scala at October 11th, 2011. 6 Comments.

Scala on Heroku (using Ubuntu): Addendums to the Tutorial

So, I thought to myself: Heroku sounds pretty cool, let’s try it out… – there is a detailed “Getting Started” out there, so what can possibly go wrong?

Right, that’s what I thought. And yet again, I have learned that I’m being a tad too optimistic.

Without further ado, here’s what went wrong for me and how I fixed what I managed to fix (as a total Ruby newbie):

Prerequisites

No problem here, registration was instant and went smoothly. – sbt 0.11, OpenJDK 6, basic Scala knowledge, all there ready to go.

Local Workstation Setup

Unfortunately, the Ubuntu readme failed me:

  • Minor nitpick, but you should have told me to run those commands as root (yes, I’m such a newb).
  • Running the commands from the readme went smoothly.
  • However, “heroku login” failed with “ruby: command not found“. Hmm… – I’m sorry, but I don’t know anything about Ruby.
  • Let’s try the usual Ubuntu magic: “sudo apt-get install ruby“. Works, yay! Now I can login to heroku from the command line just fine.

Write Your App

Finally, some Scala code, I feel right at home here.

Declare Dependencies with sbt, Add the Start Script Plugin, Build Your App

I’m cool with sbt magic, too. Everything went fine. This looks promising.

Declare Process Types With Foreman/Procfile

Foreman and Procfile? Never heard of these. No problem, I guess, looks easy and helpful. However, my Ubuntu system doesn’t know anything about Foreman either: “foreman: command not found“.

I’m stumped here. I’ve found out that it’s a Ruby gem, and that it should have been installed together with the Heroku Toolbelt. I even tried installing it via “gem install foreman” (which required installing the rubygems package first).

Why do I have to use Foreman here at all?

… turns out: I don’t. I can start my new web application via “target/start Web” just as well. Good enough for me and my experiments.

(The web application started on port 8080 for me though, not on port 5000 as mentioned in the tutorial.)

Store Your App to Git

But I don’t want to. I want to store it to Mercurial instead. Never mind me, though, everyone else loves Git, so you probably love Git, too.

Anyway, this worked like a charm.

Deploy to Heroku/Cedar

This mostly worked, too. “heroku logs” failed at first (“Logging is not enabled for this app.”). A few minutes later, however, it worked. I didn’t change anything, I swear. This is minor anyway, as activating the logging plugin would have been very easy.

And here I am, with a working Scala web app deployed to Heroku. In spite of all my nitpicking: This is cool!

Now I just have to decide what the heck to do with that web app? :)

By the way, the “slug size” of this teeny weeny little app is > 40 MB. This sounds like quite a lot, especially when Heroku tells me that 100 MB is the maximum. How come? – I don’t know. My local git repo is very small, I think. Is it the dependencies, maybe (finagle-core)?

Posted in Scala at October 10th, 2011. 2 Comments.

A few short notes on converting SBT plugins to 0.10.x

I just finished converting my FindBugs SBT plugin findbugs4sbt to SBT 0.10.x.

FindBugs? What’s that? – Go have a look at its website, and then use it, always! One caveat though: It doesn’t support Scala source code. So use it with all your Java projects.

SBT? What’s that? – It’s a Scala-based build tool called “Simple Build Tool”, and it’s cool. Have a look at it and try it out!

Anyway, if you already know about SBT and think about moving over to the new 0.10.x version, or if you even think about hacking your own plugin for it (please do!), the following quick notes may be of interest to you…

  • Read the SBT wiki page about plugins first. It’s not perfect, but it’s a good start, and you could always help improving it.
  • SBT 0.10.x has changed so much that it’s a rewrite, mostly. Give up your hope of “simply converting” your plugin.
  • However, the new settings system seems well thought-out. Forget the trait- and override-based system of 0.7.x. You know you want to.
  • You want to take a look at this SBT source file. Believe me. You just don’t know yet that you do. Knowing the settings keys is absolutely vital for hacking plugins.
  • Take a good long look at all the existing plugins‘ source code. They’re all doing different things in different ways, and all in all, there’s a lot to learn from them.
  • Quick, learn the difference between SBT tasks and commands. In my humble opinion, task plugins are probably easier to write than command plugins.
  • Don’t be afraid to read and ask questions in the SBT Google Group.
  • Don’t use SBT 0.9.9. It’s the one slow version of SBT, and I used it for most of my plugin conversion, so that you don’t have to, too. :)
  • Please don’t put everything into one plugin source file. There are other people out there who want to learn how to create their own SBT plugins, and they want to be able to read and understand your code.
  • Browse the SBT API documentation and use the stuff that’s already in there. It’s a lot, even if it’s perhaps not so easy to find your way around in there (at least it hasn’t been for me).
  • Maybe, you want to consider comparing the sbt-0.7.x and the default branch of my findbugs4sbt plugin, if you want to convert something task-based and are after a “before” vs “after” comparison.

So there you have it, a few of my insignificant and unordered plugin conversion impressions. I hope you’ve had fun reading them.

Posted in Scala at June 7th, 2011. 5 Comments.

Four reasons why SWTBot doesn’t work out (for me)

After my little blog series about Jubula, I thought I’d try out something similar using SWTBot. However, there’s no use in writing the same tutorial again for the RCP mail application because it’s already there

Nevertheless, I attempted to implement the same few tests I wrote for Jubula, and you can view the results in the piece of code below:

package de.johoop;

import static org.junit.Assert.*;

import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.swt.finder.keyboard.Keystrokes;
import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
import org.junit.Before;
import org.junit.Test;

public class FirstSwtBotTest {

  private SWTWorkbenchBot bot;

  @Before
  public void setUp() throws Exception {
    bot = new SWTWorkbenchBot();
  }

  @Test
  public void mailToolbarButtonShouldOpenMessageDialog()
      throws Exception {

    bot.toolbarButton(1).click();
    assertThatCorrectDialogIsDisplayed();
  }

  @Test
  public void openMessageMenuEntryShouldOpenMessageDialog()
      throws Exception {

    bot.menu("Open Message").click();
    assertThatCorrectDialogIsDisplayed();
  }

  @Test
  public void keyboardShortcutShouldOpenMessageDialog()
      throws Exception {

    SWTBotPreferences.KEYBOARD_LAYOUT = "EN_US";
    bot.activeShell().pressShortcut(
        Keystrokes.CTRL, KeyStroke.getInstance("3"));
    assertThatCorrectDialogIsDisplayed();
  }

  private void assertThatCorrectDialogIsDisplayed() {
    final SWTBotShell openDialog = bot.activeShell();
    assertEquals("Open", openDialog.getText());
    assertTrue(bot.label("Open Message Dialog!").isVisible());

    bot.button("OK").click();
    assertFalse(openDialog.isOpen());
  }
}

It’s a set of three tests opening the “Open Message” dialog via toolbar button, keyboard shortcut or menu entry. Simple.

At first glance, this looks neat, especially if you’re a developer: few lines of code, all directly in Java, using the already familiar JUnit framework, well supported from within the Eclipse IDE.

Nevertheless, here’s my list of things I don’t like about this:

  1. Let’s begin with a minor nitpick: I’m using a German keyboard layout, and SWTBot complains that it can’t find my layout. This means that I either have to somehow create one (which might be easy, I haven’t checked), or I have to set my keyboard layout to the US one (it doesn’t matter for my simple Ctrl-3 test).
  2. Next, I can’t write these tests in Scala for some reason (I’d really like to use Scala for my tests, so very much more concise): In Scala, the following line:
    new SWTWorkbenchBot().toolbarButton(1).click()

    fails with a compile error in Eclipse: “Access to protected method click not permitted because enclosing class object ScalaUser is not a subclass of class AbstractSWTBot in package widgets where target is defined”. – What’s that?

    If you ask me, it’s somehow caused by the SWTBotToolbarButton having an abstract public method click() returning an SWTBotToolbarButton, and inheriting from AbstractSWTBot<T>, which has an abstract protected method click() returning an AbstractSWTBot<T>.

  3. Also, I don’t want to use JUnit for system tests. JUnit is a great framework if all you do is unit tests. If you’re testing on the level of integration or system tests, however, TestNG is a way better fit if you ask me. The execution model of TestNG is a lot more flexible than that of JUnit (even if you use decorators and stuff there). For example, have a look at the data providers of TestNG. Unfortunately, there’s no TestNG integration for SWTBot.
  4. Finally, here’s what I’d call a showstopper. Have you noticed how I say toolbarButton(1) in my code instead of the toolbarButtonWithTooltip("Open Message") you’d probably expect? That’s because using the latter method will require another dependency in your plug-in project. That dependency will have to get injected into your test object, too (the RCP mail application in my case). And unfortunately, it will add toolbar buttons and keyboard shortcuts to your test object!

    In my case, this leads to Ctrl-3 suddenly not working as expected anymore: The tests have changed the behaviour of the test object! I absolutely can’t have that happening.

For me, these four reasons unfortunately mean that SWTBot is not a viable tool for automating UI tests. I would really like to use it, especially combined with Scala, for quick and easy developer UI testing; I’d be quite happy if you could refute any of my four reasons above.

I’ve still got hope that maybe I’m just too stupid to use SWTBot correctly.

Posted in Eclipse, Java, Scala, Testing at May 25th, 2011. 4 Comments.