OSGi: some criticism

Over the past few weeks, I’ve dived into the wonderful world called OSGi. OSGi is a standardized (by a consortium and soon also JCP) set of java interfaces and specifications that effectively layer a component model on top of Java. By component I don’t mean that it replaces JavaBeans with something else but that it provides a much improved way of modularizing Java software into blobs that can be deployed independently.

OSGi is currently the closest thing to having support for the stuff that is commonly modeled using architecture description languages. ADLs have been used in industry to manage large software bases. Many ADLs are homegrown systems (e.g. Philips’ KOALA) or simply experimental tools created in a university context (e.g. XADL). OSGi is similar to these languages because:

It has a notion of a component (bundles)

Dependencies between components

Provided and required APIs

API versioning

Making such things explicit, first class citizens in a software system is a good thing. It improves manageability and consistency. Over the past few weeks I’ve certainly enjoyed exploring the OSGi framework and its concepts while working on actual code. However, it struck me that a lot of things are needlessly complicated or difficult.

Managing dependencies to other bundles is more cumbersome than handling imports in Java. Normally when I want to use some library, I download it; put it on the classpath; type a few letters and then ctrl+space myself through whatever API it exposes. In OSGi it’s more difficult. You download the bundle (presuming there is one) and then need to decide on which packages you want to use that it exposes.

I’m a big fan of the organize imports feature in eclipse which seems to not understand OSGi imports and exports at all. That means that for one library bundle you may find yourself going back and fort to the manifest file of your bundle to manually add packages you need. Eclipse PDE doesn’t seemt to be so clever. For me that is a step backwards.

Also most libraries don’t actually ship as bundles. Bundles are a new concept that is not backwards compatible with good old jar files (which is the form most 3rd party libraries come in). This is an unnecessary limitation. A more reasonable default would be to treat non OSGi jar files as bundles that simply export everything in it and put everything it imports on the import path. It can’t be that hard to fish that information out of a jar file. At the very least, I’d like a tool to that for me. Alternatively, and this is the solution I would prefer, it should be possible to add the library to the OSGI boot classpath. This allows all bundles that load to access non OSGi libraries and does not require modifications to those libraries at all.

Finally, I just hate having to deal with this retarded manifest file concept. I noticed the bug that requires the manifest to end with a empty line still exists (weird stuff happens if this is missing). This is equally annoying as the notion of having to use tabs instead of spaces in makefiles. I was banging my head against the wall over newline stuff in 1997. The PDE adds a nice frontend to editing the manifest (including friendly warning of the bug if you accidentally remove the newline). But the fact remains that it is a kludge to superimpose stuff on Java that is not part of Java.

Of course with version 1.5 there is now a nicer way to do this using annotations. Understandably, OSGi needs to be backwards compatible with older versions (hence the kludge is excused) but the way forward is obviously to deprecate this mechanism on newer editions of Java. Basically, I want to be able to specify at class and method level constraints with respect to import & export. An additional problem is that packages don’t really have first class representation in java. They are just referred to by name in classes (in the package declaration) but don’t have their own specification. That means it is difficult to add package level annotations (you can work around this using a package-info.java file).

I know, I’m actually targeting embedded devices at the moment. My criticism extends a bit to the people who want to make this a core part of Java.

OSGi is useful and it solves a real problem but it is not the best solution to integration in next generation Java since it is poorly aligned with language features and essentially a hack that works around missing features in the language that have been addressed in recent years.

I”ve used it and I studied various component models (including some pretty exotic ones) and I don’t like it. If I don’t get it after that much work (i.e. I’m not worthy), I’d actually see that as confirming my central point here: it’s too damn complicated for what it does.

From my point of view OSGI is all about classloader hacks. The one classloader per component model is at the very core of the OSGI design. Without class loaders, most of the osgi magic would not work, at all.

Real modularity would come at the language and vm level. The core problem is that java (and in fact most modern programming languages) lacks modularity that goes beyond files, directories (which are implicit parts of the run-time and compiler model but not the language) and the package construct. I’m all for strong typing between modules/components but not at any cost. I don’t find the way OSGI does things here particularly elegant or easy. In fact it is quite intrusive.

Dynamicity in OSGI is in my view rather a weak spot. I find Spring a lot easier to deal with here and I don’t see much benefit in the way OSGI does this. Yet another source of complexity. Your experience of things being hard to debug when people depend on this is a clear symptom of things being less than ideal here.

Application life cycle management. Why is it that only Java applications need excessive amounts of management and most other applications can be safely kill -9ed and restarted? I’m exaggerating of course but there is an issue here of bloat, needless layers of complexity and a definite impediment to testing. I’d argue that co-locating different applications in one vm is probably a fallacy. Isolate at the OS level, not at the vm level.