Today Google Alerts dumped me into two discussions where OSGi seems to be on the wrong side of the divide regarding the KISS principle. The first is an extensive debate in the firstname.lastname@example.org mailing list, the second is the JSR 277 mailing list.
The Tomcat developers have been asked to osgify their popular web server. This resulted in a discussion that was very interesting to read. Several people seem to have a disdain for the OSGi zealots (which I guess is me) but there seems to be a general uneasiness with this request. However, my key trigger for this blog was that in this discussion I noticed that several people regard OSGi as overly complex and heavy. The JSR 277 discussion raised the same problem from another direction. From the JSR 291 interoperation discussion: "I wanted something in Java that was simpler and cleaner that OSGi-users could leverage if they wanted.". Is OSGi already ossified?
The key problem to decide this question is, as so often the case, requirements. Is Java complex? Hard to answer, if you want to write a "Hello World" it is humongous overkill. If you are writing a large scale web application it is nice to have a solid foundation. The key phrase in the definition of KISS is unnecessary complexity. Complexity is in the eye of the beholder.
First, the OSGi API is very small by any measure. There is only one mandatory package that only has 26 class files, including the security and exception classes. And you can already leverage OSGi without writing Java code. Can you call it intrusive when you can turn a JAR into a bundle by adding one or two manifest lines? All the complexity people complain about is optional. That said, I do agree that even optional things create some kind of conceptual complexity. So maybe there is a lot of cruft in the options?
Let us take a feature like import packages which is often considered hard. Most dependency mechanisms like Maven, Ivy, and also the original JSR 277 are based on the Require-Bundle concept. I.e. you declare a dependency on the wrapper.
Wrapper based dependency models are simple to understand for us humans. It would work actually very well in practice if JARs would be highly cohesive and not change their constituent packages over time. Which raises the question: Do you want the woman, or the dress?
We developers have discovered the wonders of refactoring and things do change. OSGi is a module system, it is about being able to change software while not breaking the deployments. Though import packages might be harder to understand initially than Require-Bundle, Import-Package does create more resilient systems because it minimizes coupling. That is why people that have used both systems usually decide to standardize on Import-Package (and bnd makes this quite easy).
Similar to the
uses:directive. In the Tomcat discussion it was stated that the uses directives made the manifest unreadable. It was much nicer to create a manifest by hand, it looked better. I do agree from an aesthetic point of view but who reads a manifest? The manifest is intended to be read by the OSGi Framework. The uses directive is an incredible important concept to maintain classpace consistency when the same class can be loaded multiple times through different class loaders. If you have lived in a world where this model is supported, you understand that uses have a very high value because they minimize runtime problems.
I do not say that OSGi has no unnecessary complexity at all. Obviously, the specification has been evolving over almost ten years. We have to tried to keep it is simple as possible, but we are as fallible as all of us. However, requirements have always come first in OSGi and fulfilling requirements just forbid you to make things too simple because they force you to understand the problem.
Obviously the key question is, are many of these requirements highly specialized cases not useful for the majority. Or are they just solving problems that awaits anybody that ventures into the wonderful land of modularity?