The Java 9 release introduced the Java Platform Module System (JPMS) - finally modularizing the class libraries provided by the JVM. In addition, JPMS can be used to modularize applications, enabling developers to split their applications into modules. The OSGi specification has been providing a module system for Java applications for over 20 years which also allows developers to modularize their applications into modules (a.k.a. bundles). Consequently, the question may arise about what happens when developers want to use Java modules to compose applications which are running in a container that is built using the OSGi module system?
In search of an answer to this question, two old ideas spring to mind. The first idea is an OSGi framework implementation without the module layer. The second idea is to provide virtual modules representing resources from outside the OSGi framework. Over the years, the first idea kept coming up mainly as a way to simplify migration to the service layer for existing applications. The second idea mostly was relevant in the context of bundles whose content is not managed by the framework. With the advent of JPMS it might be worthwhile to revisit the two together not only as a good transition model to the service layer or a resource-specific optimization, respectively, but as a way to bridge modules from the outside world into the OSGi framework. This insight was the impetus for the new RFP 196 tentatively called OSGi Connect.
What is OSGi Connect?
At the core, the idea is to have framework SPI hooks that allow a management agent to provide bundles whose content is not managed by the framework. More specifically, the idea is to introduce a new kind of bundle where the framework does not expect to have access to byte entries in an archive and instead allows another entity to manage entry access and more importantly bundle class loading. The ultimate goal is to reduce the need to modify the framework to support JPMS modules and other class path entries on the outside on the one hand and to represent these modules inside the framework as bundles that are still subject to the lifecycle and the service layer on the other hand.
How does it work?
At present, the idea is to use the location URLs of bundles to give the SPI a chance to take over managing the entry access and class loading for that bundle. The framework will for each bundle install ask the SPI if it handles the location given. If so, it will delegate resource and class load requests to the SPI while still representing it as a bundle inside the framework and manage the lifecycle like normal. This set-up makes it possible to represent JPMS modules and/or class path entries as bundles inside a framework and because it will use the provided class loader, services from the inside could be used on the outside as well.
What does it look like?
In the end, the result is an OSGi framework where one can install a bundle from a location string recognized and understood by the SPI implementation that will make the actual content and classes available. Since the bundle is otherwise still represented as normal, it will have its bundle activator be called and declarative services will be handled. In addition, it will be possible to have it wired up correctly i.e., other bundles will be able to wire to it and can introspect the wiring like normal. The resulting hybrid solution hopefully will ease the tension between using OSGi or JPMS for applications. Furthermore, as this approach makes it possible to have all bundle classes be loaded by the same class loader (assuming that side-by-side packages are not required) it might be useful in the context of AOT compilation where it is typically not desirable to have user-defined class loaders in the mix.
What are the limitations?
As so often in life, there is no free lunch and trying to make something look like a bundle that isn't is no exception. The OSGi framework will not be able to magically make things dynamically updatable nor can it help in making sure something obeys the OSGi modularity rules. That said, the actual limitations aside from dynamism and module layer verification are surprisingly few with maybe the biggest being that the class loader used by the SPI does not necessarily implement the BundleReference interface and some nuances around handling resource URLs.
When will it be available?
RFP 196 has been approved recently and is in the RFC phase. The expert group has started to define the SPI interfaces and prototype work has started that shows that they can be used successfully to bridge JPMS modules and class path entries into Eclipse Equinox and Apache Felix. While the actual interfaces are not yet public, we expect some early experiments to be available soon.