Tuesday, October 06, 2009

OSGi Pipe Dreams

So OSGi has been on my radar for a while. I got a chance to have a good play with it, and I don't think I actually came out on top. So rather than bore you with my tales of woe, let me describe my OSGi Utopia:

Effortless builds

Ideally, I'd be able to declare bundle in my maven pom and that would be the end of it. That's right. No messing around with bnd or bundlor configuration. As a total newbie, figuring out what should go in the manifest was arguably the hardest part. A lot of that info is contained in my maven pom, so why do I need to specify it again just for the manifest?

Effortless deployment

With a classic war, I can simply run 'mvn jetty:run' and bang!, my project is deployed to a jetty instance that magically materialises out of no where. No dicking around. Not only that, I can tell maven to start up and deploy to an embedded jetty instance which runs in the background for integration tests, and tear down that instance later. Again, with near zero configuration. I might have to give it a config file that declares my data sources etc, but that's about it.

Effortless provisioning

Again, I'll look to the maven ecosystem for a good example. Maven repositories, (I rather like Nexus in particular) can be taught about other repositories, and it can download artefacts from these repositories on the fly.

I only played with DM Server, so your experiences may vary, but as of the moment, it looks like DM Server can only look at other DM Servers for remote hosted repositories. There's an issue to get support for the main EBR, but really, why can't I just point it at our local Nexus installation, which knows how to find aforementioned bundles for my build. Why is it so hard to find the same bundles for runtime?

Another big promise of OSGi is the end of classpath hell. That is another area where DM Server has unfortunately fallen flat on it's face. It was quite easy to screw up DM Server's boot classpath, and I managed to do so by trying to shoehorn my local maven repo into DM Server.

Granted, DM Server 2.0.0 is only a milestone release, but I really don't want to place bets on something that might not exist by the time a project goes live.

In summary…

OSGi does promise a lot, but the compromises needed to make good on those promises are just not worth it, with current tools. I can live with having to fudge around manifests, or do manifest-first development, but not being able to quickly provision an environment for my bundles to run is an absolute deal breaker.

8 comments:

Mirko said...

Just as a side note. Did you know that there is a semi official spec under RFC112 (http://www.osgi.org/download/rfc-0112_BundleRepository.pdf) called OBR. Felix maintains it and as far as I know, it supports provisioning from a Nexus (Pro?) repository (via console and probably scripting as well). There is currently a lot of work going on in this direction, so maybe soon we can see a fully official and seamless repository integration. Pascal from the Equinox P2 team is currently working on that I think.

mcculls said...

FYI, if you use maven-bundle-plugin 2.0.1 then often all you need to do is change the POM packaging from jar to bundle.

It uses Maven details to configure Bnd...

http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html

You might also want to look into the OPS4J Pax projects, such as:

http://paxrunner.ops4j.org

and

http://www.ops4j.org/projects/pax/construct/

For example, try:

mvn org.ops4j:maven-pax-plugin:run

tunaranch said...

@Mirko:

Yes, I know about OBR, but I don't think DM Server supports provisioning from them at the moment.

Nexus Pro does support it, and some work has been done to get Apache Archiva to support it as well, but again, DM Server does not support either :/

That said, I still think it's a bit redundant having both an OBR and an M2 repo.

I would definitely like to see where these things go, but for now it's "Call me when I can 'maven deploy' to one".

@Mcculls
Yes, I did try maven-bundle-plugin. It gets it about 90% right. Where it mostly falls over is web modules, and it doesn't know about stuff declared in Spring applicationContexts, so it leaves some stuff out.

I had a quick play with pax, but I couldn't figure out how to deploy my project, which is bundles + web modules + dm server in one hit.

I might have to revisit this when I have some more time.

patbaumgartner said...

In this case you should use SpringSource Bundlor which parses also your XML files ... an in a newer version of BND it has a plugin to parse also your Spring XML stuff ... aQute.lib.spring.SpringComponent

tunaranch said...

@pat The big reason I didn't go with bundlor was because you had to duplicate project info, and it couldn't even convert the version number (especially if it contains -SNAPSHOT) into an osgi version.

Personally I liked bnd better, and if it could parse spring manifests and maybe supported import-template then that's one thing taken care of.

Peter Kriens said...

Wow man, you're picky :-) You want to work things out of the box for all your choices! Unfortunately, OSGi is used in many different areas and therefore has no extensive support for a specific configuration like yours.

The easiest solution seems to be Stuart's advice, use the bundle plugin. This is based on bnd.

bnd has a built-in plugin for spring, you can activate it with (I think, I do not use maven):

<_plugins>aQute.lib.spring.SpringComponent</_plugins>

If you have problems with this, let me know. Kind regards,

Peter Kriens

Mirko said...

Stuart's suggestion is actually what we are using. Works well enough for us in 99% of our cases. Here is a snippet that should get you started in no time:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.0.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<unpackBundle>true</unpackBundle>
<manifestLocation>META-INF</manifestLocation>
<!-- enable simple spring xml file analysis -->
<_plugin>aQute.lib.spring.SpringComponent</_plugin>
</instructions>
</configuration>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
</plugin>

Read through the documentation to find more tweaks to adjust it to your specific needs.

Cheers,
Mirko

tunaranch said...

@Peter Correct. Problem with being half Gen Y and a Virgo :D

In all seriousness, though, this is the first time that I've a tool be umm... stubborn, if you will.

@Mirko @Peter That extensions looks like it'll do the trick, though. That said, I might wait for DM Server to settle down, and see where OSGi Blueprints go before I get my hands dirty again.