Clojure running successfully under OSGi

Published: 3:02 PM GMT+12, Sunday, 1 February 2009 under: technology
osgi  java  functional  development  lisp  modular  clojure  github 

Functional languages, and specifically the clojure language are being talked about at the SMX offices recently and I thought it was about time I gave it a closer examination and I've always found the easiest way for me to learn about new technology/frameworks is to somehow graft it into an existing project I'm working on - and in this instance that means running clojure from an OSGi bundle.

My first step was setting up a standard clojure workflow, this led to writing a simple clojure-maven-plugin over on github which lets me compile my clojure code with a simple maven declaration:

Next comes an initial clojure lib which simply implements a known Java interface:

Whilst very simple, this small example gives us a concrete starting point to go forward - OSGi integration:

The ClojureProvidingComponent class is a simple OSGi SCR component (OSGi metadata build via the maven-scr-plugin, when this component is activated it simple gets an instance of our clojure library, and registers it as an OSGi service. That service is then looked up, and executed.

Due to some class loader related issues with clojures' current implementation, we're required to swap out the current threads context classloader whilst we construct our object (once this is resolved, we should be able to have our clojure lib be the component itself.

As our clojure library current does very little, we don't need to mess with the class loader in order to run it, however as we extend the clojure side further, I'm sure we will. As a simple work around, the service we register into OSGi could be a dymanic proxy which handles the class-loader swapping for us transparently.

As classpath entries under under Apache Felix used their own protocol, one part of clojure still needs to be patched in order to work:

All in all, getting clojure to work under OSGi wasn't as hard as I expected, thou I expect to find other issues once I start to add actual functionality to the clojure library side of things.

Comments (4)

What's involved in getting this to work within the Confluence plug-in framework?

see: http://forums.atlassian.com/message.jspa?messageID=257300714#257300714

left by michael thorne . Thursday, 30 April 2009 9:16 AM

Clojure looks nice from the concurrency side of things, but there's A LOT that I don't like about it, personally I'm still leaning towards Scala for my 'next favorite language', thou I've not done much seriously with it either yet.

left by Mark Derricutt . Wednesday, 4 March 2009 9:27 AM

Use Groovy 1.6 - then it is pre-built for use in OSGi :-)

Seriously - why clojure? A functional language sitting on the JVM even more obscure than Scala?

left by RIchard Vowles . Wednesday, 4 March 2009 9:22 AM

As you've just pointed out to me on Twitter, this approach embeds clojure-lang.jar in the Bundle-Classpath of the bundle.

This is fair enough, but what about when other bundles also want to use Clojure? If they each embed clojure-lang.jar then they will each create a copy of the Clojure runtime and standard library, because Clojure is implemented entirely with static initialisers, methods and fields. This is expensive (2+ seconds to start a Clojure runtime on my 2.33GHz MacBook Pro) and also prevents the bundles talking to each other (they will get ClassCastExceptions passing around instances of standard library classes, because each one will load those classes independently).

So the challenge is to get Clojure to work across multiple bundles with just one copy of the runtime and standard library classes. That's what I tried and failed to do. I hope you have more luck!

left by Neil Bartlett . Sunday, 1 February 2009 9:53 PM
Add Comment