Wednesday, February 9, 2011

Starting with Akka 1.0

Since version 1.0 of Akka is coming out very soon, I thought it might be handy to write a quick new post on getting started with Akka again since a couple of things have gotten quite a bit easier.

Development setup
I am using the following tools:
Install these tools by following the links. I am using sbt-idea as a sbt processor (see sbt-idea link). idea-sbt-plugin is a plugin that you can use to run sbt from within IDEA. Add the Scala plugin and idea-sbt-plugin (look for SBT) in IDEA by using the plugin manager (Settings-> Plugins).
After you have installed these tools you first need to create an sbt project. So lets do that first. ($ means I'm typing in the console, > means I'm in sbt, scala> means I'm in scala interpreter)


Minimal setup
$ mkdir akkastart
$ cd akkastart
$ sbt
press Y to start a new project, fill in some details like name, organization, version, scala version (2.8.1), sbt version (0.7.4) and wait for sbt to download scala and sbt dependencies.
This should create a lib, project, src and target directory. Create a project/build/ directory, add Project.scala to it with the following content:
import sbt._
import sbt_akka_bivy._

class MyProject(info: ProjectInfo) extends DefaultProject(info) with AkkaProject{
}

Create a project/plugins directory and add a Plugins.scala to it with the following content:
import sbt._

class Plugins(info: ProjectInfo) extends PluginDefinition(info) {
  val bumRepo = "Bum Networks Release Repository" at "http://repo.bumnetworks.com/releases"
  val AkkaRepo = "Akka Repository" at "http://akka.io/repository"
  val akkaPlugin = "se.scalablesolutions.akka" % "akka-sbt-plugin" % "1.0-RC6"
  val sbtAkkaBivy = "net.evilmonkeylabs" % "sbt-akka-bivy" % "0.2.0"
}

The akka plugin makes getting all the dependencies and modules for akka extremely easy. The bivy plugin is just really handy for deployment.
Then run sbt update. this will add a lib_managed directory with the minimal dependencies for Akka. add akka modules to the Project.scala file if you expect to use them, for instance akka-camel:

import sbt._
import sbt_akka_bivy._

class MyProject(info: ProjectInfo) extends DefaultProject(info) with AkkaProject{
  val akkaCamel = akkaModule("camel")
}

run sbt update after adding akka modules.
Now we can generate an idea project from the sbt project by running sbt idea: (if you followed installation instructions for sbt-idea as processor from the sbt-idea page)

$ sbt idea

That creates a .iml file your directory and a .idea directory with all the stuff Idea needs. (it also creates a .iml for building the sbt sources like Project.scala)

Now open the .iml file with Idea. Everything should just work (Don't you just love it when that happens? :)
Making your module (Build->Make Module akkastart) builds in the same target directories as sbt would.
Add an akka.conf to src/main/resources (so it gets on your classpath) if you don't like the defaults, check here on akka.io for more information. At first you probably don't need an akka.conf yet, when Akka finds no config it sets up defaults.

That's all there is to it, now you can start adding your Actors in src/main/scala as you see fit.
Of course you can also just do something like this to get that quick scala console fix (output in italics):

$ sbt
> console

scala> import akka.actor.Actor
import akka.actor.Actor
scala> class PrintActor extends Actor {
     |  def receive = {
     |   case s:String => {
     |     println("received:"+s)
     |   }
     |  }
     | }
defined class PrintActor
scala> val actorRef = Actor.actorOf(new PrintActor)
23:28:45.830 [run-main] WARN  akka.config.Config$ - 
Can't load 'akka.conf'.
One of the three ways of locating the 'akka.conf' file needs to be defined:
1. Define the '-Dakka.config=...' system property option.
2. Put the 'akka.conf' file on the classpath.
3. Define 'AKKA_HOME' environment variable pointing to the root of the Akka distribution.
I have no way of finding the 'akka.conf' configuration file.
Using default values everywhere.
actorRef: akka.actor.ActorRef = Actor[PrintActor:f55f3eb0-349b-11e0-ae19-0019d2b39ec9]
scala> actorRef.start   
23:28:59.710 [run-main] DEBUG a.d.Dispatchers$globalExecutorBasedEventDrivenDispatcher$ - Starting up Dispatchers$globalExecutorBasedEventDrivenDispatcher$[akka:event-driven:dispatcher:global]
with throughput [5]
res1: akka.actor.ActorRef = Actor[PrintActor:f55f3eb0-349b-11e0-ae19-0019d2b39ec9]
scala> actorRef ! "test"
23:29:03.412 [run-main] INFO  a.d.LazyExecutorServiceWrapper - Lazily initializing ExecutorService for 

scala> 23:29:03.428 [akka:event-driven:dispatcher:global-1] DEBUG akka.dispatch.MonitorableThread - Created thread akka:event-driven:dispatcher:global-1
received:test

For some more examples you can check these here on github, I've updated them to 1.0-RC6.


Happy hAkking!

6 comments:

  1. Now al you need is to add the sbt plugin to your idea installation, so you can use sbt in a idea dialog to also quickly build your and code/tests.
    See: https://github.com/orfjackal/idea-sbt-plugin

    ReplyDelete
  2. Hi momania,

    Thanks for the link to idea-sbt-plugin. I got so used to using an extra terminal with sbt in it that I've never really taken the time to try that plugin. I'll check it out again thanks.

    ReplyDelete
  3. I added the link to idea-sbt-plugin to the post. It's quite nice although I'm not sure how you cancel the background tasks if something goes wrong in sbt. still the compiling with sbt automatically and the highlighting in the console works very nice.

    ReplyDelete
  4. This was a huge help.

    Is there any way using the akkaModule command to exclude dependent modules? I'm trying to "akkaModule("http")", but according to the docs from Akka, I should exclude Jetty. However it doesn't look like their ivyXML command works in conjunction with akkaModule. Is this possible?

    Sorry if this is a silly question...just getting up and running with Akka.

    ReplyDelete
  5. Hi kahuna,

    The exclusion of jetty is only necessary if you want to run akka http from inside sbt with jetty run AND if you use sbt 0.7.4. If you use 0.7.5.RC0 you don't have to exclude it.
    The command in the docs should work. if the override does not work that would be an sbt issue, just double check if you got the override right (http://code.google.com/p/simple-build-tool/wiki/LibraryManagement)

    As far as I know, akkaModule is just a convenience method to define a dependency:

    def akkaModule(module: String) = "se.scalablesolutions.akka" % ("akka-" + module) % akkaVersion

    So I think you can use intransitive in sbt if you don't want to pull in transitive dependencies, but then you will have to get all other dependencies yourself.

    Hope this helps, if it doesn't, have you tried asking this question on the akka user list? the guys over there are very helpful (http://groups.google.com/group/akka-user)

    Let me know if this answer works for you.

    ReplyDelete