Those following the OSGi draft specifications will have seen that the OSGi Alliance has been working in the area of "bundle collections" for quite some time. By bundle collections, I mean the ability to define and deploy a set of bundles as a single entity. Many OSGi runtimes already provide such capabilities, and some example include:
- Apache Aries Applications
- Apache Geronimo Applications
- Apache Karaf Features
- Eclipse Virgo Plans and PARs
- Eclipse Platform Features
- IBM WebSphere Application Server Applications, Composites and Features
- Oracle GlassFish Applications
- Paremus Service Fabric Systems
When you see a list that long, and I've no doubt there are many more, it's clear that this is an area crying out for standardization. Digging a little deeper on these bundle collections, we see a lot of commonality between them; they define collections of bundles (obviously), they give the collection an identity, they allow version ranges when identifying the content bundles, and they also often allow locking down of versions (e.g. for a specific tested deployment). There's also some variability; many, but not all, provide isolation to prevent undesirable interactions between collections deployed to the same runtime. This is similar to the isolation you get with Java EE applications on an applications server, but rather than replicating the Java EE model, they also allow bundles to be shared by applications to remove duplication and reduce disk and memory footprint (allows common libraries and frameworks to be packaged and deployed just once). Other types of collections do not impose isolation and are often used as a way to simplify the assembly of runtimes.
So, where are we in the standards? Well, there are two parts to this:
The first part is an enabler in the OSGi Core Framework. To enable isolation to be applied to collections of bundles, the OSGi Core defined a set of framework hooks. Hooks hide things from bundles such that they cannot resolve to, or find, them. Core 4.2 had already added the Service hooks and Core 4.3 complemented these with Resolver and Bundle hooks. Hooks are a low-level core features. It was never the intention that these would be used by most OSGi developers, and so something else was needed.
The second part is the specification that uses the core enabler, but makes it simple to develop, test and deploy these bundle collections. That's where the new Subsystems specification comes in. Subsystems defines a programming model that uses a format familiar to bundle developers for developing bundle collections. It simplifies the task further still by defining different types of bundle collection which have default isolation policies matching the most common isolation models. The subsystem types defined in the specification are:
- Application - allows the collection to use packages and services from shared bundles, but does not share its own with others. This type fits closely with what people would typically think of as an application running in an application server
- Composite - does not use or share any packages or services unless explicitly configured to do so. This enables the collection of bundles to keep some aspects of their internals private, only exposing what they want the rest of the runtime to see or provide. A common use case for composites is where you have teams providing parts for solutions and those parts are composed of multiple bundles and have public APIs and then implementation details they do not wish to be externalized.
- Feature - freely uses and shares any packages and services it provides or are visible to it. This simplifies the management of bundle collections but does not isolate them. A common use case for these is to make the definition of runtimes or solutions simpler.
The following is an example of an application subsystem containing three bundles:
Subsystem-Name: Acme Foo Application
If you've developed bundles in the past, then many of the headers will look familiar. This particular application has a name (Subsystem-SymbolicName) and a version (Subsystem-Version), including human readable information (Subsystem-Name). It has a type (Subsystem-Type) that identifies it as an application which means its packages and services are not exposed outside the subsystem. Finally, it lists its content (Subsystem-Content). The type of the content defaults to bundle, but other types are permitted (such as fragments, or other subsystems, e.g. to nest a feature within an application), and a subsystem implementation can also choose to enable its own custom types (not required to be supported by different subsystem implementations).
One other important area of management that subsystems addresses is that of provisioning. You'll see from the example that it lists content but not the specific versions, nor any bundles it might require in support of that content. If you install that definition and provide no further details, it will resolve the subsystem to choose the exact bundle versions and any necessary dependency bundles. A second option is to provide a pre-defined deployment that specifies the exact content and supporting bundles. That way, you can test a specific deployment before putting it into production.
The Subsystem specification was made available in the OSGi Enterprise Release 5 Proposed Final Draft in March. As with all OSGi specifications, they're written for implementors, but as projects and vendors begin to provide implementations I expect to see user-level documentation emerge and then users can enjoy the flexibility of creating modular standard applications, composites and features for a number of target environments.