An OSGi Bundle… built in Scala
Scala is really hot at the moment – even the Java Posse lads are talking about it! Scala seems to provide the ideal pragmatic mixture between functional programming and interoperability with Java.
So I wondered if it was possible to build an OSGi bundle with it, and if so whether there would be any benefit in doing so. As it happens, yes you can, and yes there is!
Unfortunately you can’t use Eclipse PDE (Plug-in Development Environment) at the moment for this. Even though there’s a reasonable Scala plug-in available for Eclipse, it doesn’t integrate with PDE properly. I did try creating a Scala project (which is basically just a Java project with an extra “nature” and builder), and then adding the PDE nature to it (using PDE Tools -> Convert Projects to Plug-in Projects…). But PDE removed the Scala plug-in’s special classpath container, and then the Scala builder barfed.
So here’s a simple tutorial, in the style of my “Getting Started” OSGi tutorial on EclipseZone, but this time we’re going to build the bundle in Scala. What we want is a bundle that, when activated, will print a list of currently installed bundles.
package scalaosgi;
import org.osgi.framework._
class Activator extends BundleActivator {
def start(context: BundleContext) {
var bundleNames = context.getBundles()
.map (b => b.getSymbolicName())
.filter(b => b != context.getBundle());
Console.printf("Installed bundles: {0}",
bundleNames.toString());
}
def stop(context: BundleContext) {
}
}
We can see several interesting things from this code sample. Firstly, it’s trivial to implement a Java interface or extend a Java class using Scala. Here we’re implementing the OSGi BundleActivator interface. The most interesting part though is the first line inside the start method, which illustrates three really cool functional programming features all in one line: type inference, higher-order functions, and lambda abstraction.
Type inference means we didn’t have to explicitly state the type of the bundleNames variable - the compiler is able to work it out for us, so we only have to say “var“.
A higher-order function takes a function as one of its parameters. In Scala, functions are objects, so they can be easily passed into functions as parameters or returned as results. The higher-order function here is “map”, which is used to map a function over each entry in a list or array and returns a new list or array containing the results of that function.
A lambda abstraction is simply an anonymous function, which in Scala is indicated with the => syntax. Here our lambda is (b => b.getSymbolicName()), i.e. a function which takes an object and returns the result of calling the getSymbolicName() method on that object.
The result of all this is a very concise line of code which would probably have to be done like this in Java:
Bundle[] bundles = context.getBundles();
String[] names = new String[bundles.length];
for (int i = 0; i < bundles.length; i++) {
names[i] = bundles[i].getSymbolicName();
}
Okay, this isn’t such a terrible piece of Java code, but to a functional programmer it looks like mostly boilerplate. It also doesn’t compose very easily. In the Scala example we could easily add a filter to remove our own bundle from the output:
var bundleNames = context.getBundles()
.filter (b => b != context.getBundle())
.map (b => b.getSymbolicName());
In Java we would have to do this with an if block inside the for loop.
Anyway how to we compile and run this? As in the “Getting Started” series, I’ll assume you’ve taken a copy of the Equinox OSGi runtime as equinox.jar. See the first installment of the series for instructions if this is not clear.
After copying the above Scala class into a file, scalaosgi/activator.scala, we can compile it with the command:
scalac -classpath equinox.jar scalaosgi/activator.scala
Now we need a Manifest, so copy this into scalatest1.mf:
Manifest-Version: 1.0
Bundle-Name: Scala Hello
Bundle-Activator: scalaosgi.Activator
Bundle-SymbolicName: ScalaHello
Bundle-Version: 1.0.0
Import-Package: org.osgi.framework, scala, scala.runtime
Remember, the final blank line is vital! Now build the JAR with:
jar cfm scalatest1.jar scalatest1.mf scalaosgi/*.class
We’re also going to need a “bundle-ized” (or “OSGified”) version of the Scala library. That can easily be created using the “Plug-in from Jar” wizard in Eclipse, but to save you some hassle I have prepared a Manifest file that can simply be injected into the existing Scala library jar. To do this, take a COPY of scala-library.jar into the current directory, and also download the manifest file at http://neilbartlett.name/downloads/scalaosgi.manifest. Then run the command:
jar ufm scala-library.jar scalaosgi.manifest
Finally we’re ready to launch Equinox and test our code:
$ java -jar equinox.jar -console
osgi> install file:scalatest1.jar
Bundle id is 1
osgi> install file:scala-library.jar
Bundle id is 2
osgi> start 1
Installed bundles: Array(org.eclipse.osgi,ScalaHello,
scala_library)
That’s it for the moment. I’ve only just started learning Scala so there are probably some newbie mistakes and stylistic oddities in what I’ve done.
My first impressions of Scala? Pretty good! It has nowhere near the power and elegance of Haskell, but it’s a big improvement on Java.


Ismael Juma:
You can get a slightly nicer version in Java using the enhanced for loop (if statement not included to match the Java example):
List names = new ArrayList(); for (Bundle bundle : context.getBundles()) { names.add(bundle.getSymbolicName()); }
April 6, 2007, 2:45 amIsmael Juma:
Well, it looks like the generic tags were removed, but it should have been a List of Strings in the example…
April 6, 2007, 2:48 amPeter Bona:
“Even though there’s a reasonable Scala plug-in available for Eclipse” Do you have a link for this plug-in? Thanks.
April 6, 2007, 10:09 amNeil:
Peter,
Sure, it’s on the main Scala language site:
http://www.scala-lang.org/downloads/eclipse/index.html
Regards Neil
April 6, 2007, 10:12 amSébastien Letélié:
And what about the same in Groovy ?
April 6, 2007, 9:46 pmNeil:
Sébastien,
I have no interest in Groovy, but I’m sure it’s possible nonetheless.
Neil
April 9, 2007, 11:08 pmStephane:
Does the following (generated) MANIFEST.MF work for you (in replacement to scalaosgi.manifest) ?!
http://lamp.epfl.ch/~michelou/MANIFEST.MF
Regards. Stephane
May 15, 2007, 5:43 pmNeil:
Hi Stephane,
Thanks for the comment! Unfortunately there is an error in your version string. It should be in the format
major.minor.micro.qualifier, i.e. with periods between each part; you have used a dash between the “micro” and “qualifier” parts. However once that error is corrected, it works perfectly.I’m delighted that you’ve taken an interest in my post, because it would be great to improve Scala’s OSGi support out of the box. I hope I can help - I will correspond with you privately about this.
Neil
May 15, 2007, 6:40 pmTom Watson:
I got the latest scala plugin to work with PDE in 3.3 RC4 by first creating a PDE project and then editing the .project file to add the scalabulder and scalanature. In the end my and sections looked like this
org.eclipse.jdt.core.javabuilder org.eclipse.pde.ManifestBuilder org.eclipse.pde.SchemaBuilder ch.epfl.lamp.sdt.core.scalabuilder
ch.epfl.lamp.sdt.core.scalanature org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature
I did not need the scala classpath container as long as I had the proper dependencies specified in the manifest to access the scala-library. For simplicity I did this by using Require-Bundle to get the scala library:
Require-Bundle: scala_library
This of coarse assumes you placed the latest scala-library.jar which is a proper OSGi bundle into your PDE development target.
June 12, 2007, 4:25 pmTom Watson:
Sorry, the XML did not show up correctly in my comment
What I did was add the buildCommand and nature sections from a scala .project file to my PDE .project file. Then it all seemed to work file.
June 12, 2007, 4:29 pmNeil:
Cool, thanks Tom! I tried pretty much the same with an earlier version, so something must have got fixed.
Now to try developing Eclipse plug-ins/RCP apps in Scala!
June 12, 2007, 4:43 pmslim ouertani:
hi, Neil,
Nice post, I try to download scalaosgi.manifest but with no success. could you please update the link.
thanks in advance.
August 1, 2008, 7:54 amphilip andrew:
Hi, Is there any way to automate this ? For example, if I have a Scala class in a test.scala file. I have my scala program running (my server is a osgi felix) and I want it to compile, make osgi and activate in my server. Then I want to be able to call a method in the class. I want this loop to be automated, in the sense that the scala code calls some function to do all of this for me, given the source of the scala file. Any suggestion I hope?
December 20, 2008, 9:41 amRafael Chaves:
I guess it is too late to mention that, but it seems in the full listing, the order between map and filter is inverted (should filter, then map). When you talk about doing filtering, the order is correct though.
May 3, 2009, 7:31 amKnowtu » links for 2009-05-18:
[...] Neil’s point-free blog » Blog Archive » An OSGi Bundle… built in Scala (tags: scala osgi) [...]
May 19, 2009, 1:05 amA New Year’s Declaration : Software & Technology @kirkk.com:
[...] at the heart of the platform, it doesn’t matter what language you use. Neil showed us how to do it with Scala way back in 2007. And Groovy does OSGi, as does Clojure. Yep, so does Scala. So no matter which language you use, [...]
January 5, 2010, 7:16 pm