OSGi
From APIDesign
OSGi is a specification of a modular system for Java. It defines packaging format (JAR file with additional manifest entries and associated troubles), runtime behaviour and a way to register and discover services. In contrast to NetBeans Runtime Container, it supports package dependencies. Otherwise the systems seem similar which has been demonstrated by implementing OSGiAndNetBeans bridge.
Contents |
OSGi Weirdness
OSGi and NetBeans Runtime Container are similar, however the devil lies in details! From time to time I manage to learn more about OSGi and then I just cannot stop wondering what was a motivation to design such behavior! Maybe this is all caused by my pre-occupation (as a designer of NetBeans system), but I just cannot overcome a feeling that certain design decisions in OSGi are just weird.
I'll nitpick on OSGi here hoping somebody will be able to explain the history and possibly also rationale behind these (mis)behaviors.
Start/Stop a Bundle
I believe it make sense to tell a module that it is going to be used or it is used no longer. Of course, I'd rather preffer Declarative Programming, but sometimes there is just no way around. Parts of infrastructure need to be turned on programmatically. Thus it is makes sense to have a BundleActivator or ModuleInstall (in the NetBeans case). However then one finds out that people can use an OSGi bundle without starting it!
What kind of crazy idea is that? It basically means I cannot put any initialization logic into the activator/installer at all. I need to be ready for somebody using my module without starting me! I really don't get the purpose of this construct at all. The NetBeans ModuleInstall is guaranteed to be called whenever somebody tries to enable a module, or use it (by having a dependency on it and trying to get enabled). This sounds logical to me.
Obviously these misconceptions complicate the OSGiAndNetBeans bridge. Basically it means there is no 1:1 mapping between enabling a module in the NetBeans sense and starting a bundle in the OSGi sense. As we discover more and more OSGi based systems (like JDeveloper), we need to add more and more flexibility to cover all the possible ways people deal with the dichotomy between used and started. OSGi is more flexible, but not logical.
Stopping Order
Another thing related to activators is the order of starting and stopping bundles. Again, if we think about the starting to be associated with use, then it makes sense to start the modules that are used by others sooner, then starting the others. Do a topological sort based on interbundle dependencies and then start the bottom bundles first (with as less dependencies as possible). When stopping a set of bundles, do it from the top. Natural? I think so. Do you think OSGi does that? No, not at all.
I've just needed to deal with a NullPointerException caused by the fact that org.eclipse.equinox.registry is stopped sooner than org.eclipse.equinox.security when calling OSGi framework.stop(). What happened? There is a singleton in the registry and BundleActivator.stop() clears it. But still the module remains available for others to call. When the system tries to stop the security bundle, it calls into the registry trying to obtain the singleton and guess, it is not there!
Why could not the great minds behind OSGi create a specification that would sort the modules using a topological sort before shutting them down? Is that unnatural? No. But rather than that OSGi introduced start levels (which we now have to support in NetBeans). The only conclusion one can have: OSGi is not well thought out.
Range Dependencies
One of characteristics of OSGi is use of RangeDependencies which seems like a clever good idea supporting cluelessness in its way, but at the end it is just a way to NP-Complete problems. An example when simple, less powerful systems would be more effective. Looking from this point of view: OSGi is over designed.
Executive Summary
I value OSGi for its ability to play a common ground, allow interoperability between various module systems (like Glassfish, Eclipse, NetBeans, JDeveloper, etc.). Only by having OSGi around we could suggest JDeveloper team to consider the idea of reusing Netbinox and sharing bits of NetBeans. OSGi is good for interoperability.
However beyond that I just can't help myself to think about OSGi as over designed, sometimes misdesigned technology. In addition to that I'd like to point out that OSGi is so 2000-late. OSGi spec 4.2 still runs on JDK 1.3 and that shows. These days the Java is different. With the help of AnnotationProcessors it can do magic (and it does not need to be a poor and misleading trick like MagicalStrings).
I fully understand the value of pioneers. Somebody just has to be the first (well second), walk the road and find out that this is not the right path. I believe OSGi succeeded in this mission. Everyone should understand now the value of modularity. Everyone should also see, that the OSGi path, is not the right one to follow. I just hope the next attempt to standardize module system for Java will learn from mistakes of its predecessors (OSGi and NetBeans Runtime Container).
Let's use the OSGi for interop for now, and then let's forget about it.
<comments/>