« Wubi : Windows Linux dual boot the easy way, when virtualization is not an option | Main | Versioning and .NET's run-time »

February 17, 2009

OSGi: Versioning and Java's run-time

When the topic of OSGi comes up it often comes hand-in-hand with the term versioning. In short: 'Java has no support for versioning and OSGi does, so OSGi fills this void'. But how does this versioning mechanism work and what implications does it have for a Java application? This post will attempt to summarize how OSGi, versioning and Java's run-time fit together.

[Entry continues to the left and below ad ]

Java's run-time loads classes from either .class files or the more common .jar file -- which is simply a group of .class files. But what happens if among these JAR files, there is more than one copy of a file named Utilities.class?

If the Utilities.class is part of your application and you keep very tight source code versioning, then you will likely won't even notice this issue. After all, if its an identical Utilities.class that is inadvertently placed in multiple JARs there won't be any discrepancies.

But now, lets assume that even though you keep tight source code control, you require adding some new functionality to the Utilities.class, that will unfortunately disrupt some earlier logic you had on it. Well, since some other part of your application already depends on the Utilities.class your opening up yourself to trouble.

Would it not be easier to have a Utilities.class version 1.0 and let the old part of the application use that, and also have a Utilities.class version 2.0 and let the new part of the application load this new version? This would avoid any possible disruption of course, but Java's run-time doesn't support this, only OSGi does.

How so? By explicitly declaring what classes a JAR can see in text snippets inside a JARs MANIFEST.MF file. So for example, lets assume the old JARs that compromise your application require Utilities.class version 1.0, you would need to add a statement like the following to your JARs MANFIEST.MF file: Import-Package:myapp.utilities;version:1.0.0; (Note: OSGi versioning is based on the coarser level Java packages, not indvidual classes).

And what about the newer part of the application, the one requiring Utilities.class Version 2.0 ? Simple, to those JARs requiring the use of this new class version you would simply add the following to their MANFIEST.MF file: Import-Package:myapp.utilities;version:2.0.0;.

The catch of course is that OSGi is the one charged with managing this versioning and visibility process. Nevertheless, its a powerful approach and one that is almost done unobtrusively within Java's run-time, so much so, that it's why OSGi has been slated to be incorporated into acknowledged by Java's standards (See Java JSR-291 ) [See comment thread for clarification on 'incorporated' vs. 'acknowledged' edit] .

If you take this versioning approach and apply it to third party Java libraries -- like those belonging to logging, frameworks and other utilities -- it can be even more compelling, because multiple versions of the same library can co-exist in the same JVM. Each application JAR can simply specify which version of a library it wishes to see, without the need to worry about backward-compatibility, conflicting logic or what a library creator will do in future versions.

If you care to read more about OSGi -- including a working sample of an OSGi web application -- you can read a sample Chapter on OSGi (to the left hand side in 'Book Extras') from a book I recently finished called 'Pro Spring Dynamic Modules for OSGi™ Service Platforms'.

Of course, if your looking for more in-depth OSGi coverage and are into server-side Java development, you might want to take a look at the entire book:

Posted by Daniel at February 17, 2009 4:46 PM