OSGi: ‘the most simple possible solution.’
“How did OSGi get that way?”
This is the question Neil Bartlett sets out to answer in his blog post ‘OSGi, and How It Got That Way.’
The most common argument against OSGi adoption that Bartlett has encountered, is that it is too complex. He admits that, on the surface, OSGi may look like a complicated module system for the Java Platform but, when you factor in all the issues that OSGi attempts to address, he concludes that it is “the most simple possible solution that satisfies those requirements.” To prove this point, he conducts a thought-experiment, where he considers each problem and comes up with a solution – which leads him to ‘creating’ something that sounds remarkably like OSGi.
The first issue he tackles, is how to separate modules, in a way that ensures classes from one module do not have the option of seeing and obscuring classes from other modules. To achieve this, he creates a class loader for each module, as class loaders can only load classes it is explicitly aware of.
However, when this class loader is implemented, the modules will be completely isolated, and therefore unable to communicate with one another. To rectify this, he re-introduces the ability for modules to see one another, whilst maintaining the ability for modules to hide some of their implementation details for one another.
He then approaches the issue of granularity in imports and exports. He cites the varying nesting levels of Java, as a reason not to define the sharing level in terms of methods and fields. “It would be simply insane to export some methods of a class but not others,” he says, theorising that the result would be countless bugs, as classes are not designed to be split apart at runtime. But, at the other end of the scale, he is against the idea of the sharing level being set at entire modules, as this would bar modules from hiding some of their implementation from one another. The result, would be what Bartlett calls “bought-the-whole-shop syndrome.”
Classes could potentially be the sharing level, but Bartlett dismisses this on the grounds that classes are too heavily dependent on other classes inside the same package. Therefore, he chooses packages as the sharing level: “it is not too onerous to list packages as imports and exports, and it doesn’t break anything to put some packages in one module and other packages in another module.” Bartlett acknowledges that this isn’t a perfect solution. In making this decision, he sacrifices the ability to handle split-packages cleanly, as the packages are all imported from a single module. If the contents of a package are spread across multiple modules, then problems will occur but, to Bartlett, setting packages as the sharing level is the only sensible and logical solution given the options.
So, does this model look familiar?
Bartlett admits that some areas need improvement, and gives the specific example of versioning, but he concludes that, before you dismiss OSGi as too complex, you should consider the problems it is designed to overcome. And, after being presented with each problem, it is difficult to argue that OSGi doesn’t find logical workarounds to thorny programming problems. The solution may not be easy, but neither are the problems.