Next Monday I will talk about
OSGi on Scala at OSGi DevCon Europe 09. As I have already given this talk twice (OSGi DevCon 09 and JAX 09), I am currently searching for some kind of fresh and cool style. Sitting in a very lonely German town I have come up with a crazy idea: Why not do the (short) talk using Scala's REPL (the interactive Scala console) instead of slides? To be honest, I am not yet sure whether to go this way, but my trials were very facinating and hence I would like to share my experiences with you.
OK, one step back. What exactly am I talking about? Well, fairly simple: Run the Scala REPL, launch OSGi (Felix, because it is very easy to launch/embed) to get a
BundleContext (of the system bundle) and do some
ScalaModules tricks to show the power of this DSL for OSGi.
In order to have Felix and ScalaModules on the classpath we have to copy felix.jar (currently using 1.8.0), scalamodules-core-1.1-SNAPSHOT.jar and scalamodules-util-1.1-SNAPSHOT.jar to a local directory and run Scala like this:
scala -cp felix.jar:scalamodules-core-1.1-SNAPSHOT.jar:scalamodules-util-1.1-SNAPSHOT.jar
scala>
First let's import some important stuff:
scala> import org.apache.felix.framework._
import org.apache.felix.framework._
scala> import org.scalamodules.core.RichBundleContext._
import org.scalamodules.core.RichBundleContext._
Then let's create and start Felix and get the BundleContext (which subsequently will be implicitly converted into a RichBundleContext):
scala> val felix = new Felix(null)
felix: org.apache.felix.framework.Felix = org.apache.felix.framework [0]
scala> felix.start
scala> val ctx = felix.getBundleContext
ctx: org.osgi.framework.BundleContext = org.apache.felix.framework.BundleContextImpl@e0c389
Then let's create a service interface:
scala> trait Greeting { def hello: String }
defined trait Greeting
Now let's use ScalaModules to (try to) get a Greeting service and use it. If you are experienced in OSGi you will know that for this task you would have to get a ServiceReference, check for null, get the service, check for null again and finally unget the ServiceReference again => Fairly low-level and involved. Now look at ScalaModules:
scala> ctx getOne classOf[Greeting] andApply { _.hello } match {
| case Some(s) => println(s)
| case None => println("No Greeting service available!")
| }
No Greeting service available!
OK, now let's register a Greeting service:
scala> val greeting = new Greeting { def hello = "Hello" }
greeting: java.lang.Object with Greeting = $anon$1@6159e9
scala> ctx registers classOf[String] theService greeting
:13: error: type mismatch;
found : java.lang.Object with Greeting
required: String
ctx registerAs classOf[String] theService greeting
^
As you can see, service registration with ScalaModules is type-safe at compile time. Hence let's do it right now and try to use it once more:
scala> ctx registerAs classOf[Greeting] theService greeting
res4: org.osgi.framework.ServiceRegistration = ...
scala> ctx getOne classOf[Greeting] andApply { _.hello } match {
| case Some(s) => println(s)
| case None => println("No Greeting service available!")
| }
Hello
There a lot of other things we could do the easy way using ScalaModules instead of OSGi API. I will show some more of these at my talk at OSGi DevCon Europe 2009, but first I have to decide whether using REPL for the talk is a good idea. What do you think?