OSGi Compendium 5 Adds Subsystems, Repositories and More
The compendium is a collection of services, along with versioning information and API definitions, that need not be part of a core OSGi release but may be used in a modular fashion by applications. Equniox, Felix and other OSGi projects have implementations of some (but not necessarily all) of the OSGi compendium specifications.
Readers may be surprised that the Service Tracker API and the SCA Configuration API are no longer present in the Compendium; however, they have been migrated to Core and Enterprise respectively. The APIs bear the number of the RFC that created them (701 for Tracker, and 129 for SCA Configuration); with the recent opening of the review process some of the specifications can be seen on GitHub.
What, therefore, is new in the Compendium release 5? Well, ConfigAdmin – used to pass configuration information on to bundles – has had a version upgrade from 1.4 to 1.5; and there are a number of new APIs including the Repository Service, Service Loader Mediator, Subsystem, Common Namespaces and Resolver Service.
Config Admin 1.5 now includes a new specification for targeted PIDs. This uses specially formatted PID (Persistent IDentity) names, using vertical bars, to target different versions of bundles. For example:
The persistent identifier can contain information for a specific bundle, using its Bundle-SymbolicName and Bundle-Version (or even its installed location) to narrow down configuration for a specific option. At run-time, the most specific configuration set is used, in much the same way that internationalisation routines in the resource bundles for Java use a targeted value for a specific language, if available. There are additional changes for the managed service factories that can use this new targeting logic.
Repository Service and Resolver Service
The Repository Service works in conjunction with the Resolver Service to abstract away the storage and network protocols of specific repository types (such as Maven, P2, OBR, NuGet etc.) and provide a means to resolve constraints against one or more of these repositories. The constraints use the generic OSGi Requirement Capability, which represents a set of things needed by a particular OSGi module (such as package imports, minimum runtime environment, and filters such as platform or processor).
Unlike repositories such as Maven Central, the OSGi repository requires a detailed knowledge of the components it contains, and the ability to return a comprehensive XML description of the full set of contents. This works well for local file-based repositories (which can be crawled to generate a full set of metadata) but may not scale to larger repositories. The repository specification has been done before, in the form of
obr; the difference with this specification is that it can potentially encompass other repository types such as P2.
To ensure that dependencies are resolved, the resolver service can take a generic set of requirements, and knowledge of a set of assets, and be able to provide a plan for which assets are internally consistent with the requirement. In the Maven world, this is similar to Aether's resolving capability; for OSGi, this is provided by runtime engines such as Equinox and Felix for resolving bundles based on a set of local JARs. The resolver service provides this mechanism as an external service, allowing tools and utilities to take advantage of these previously internal APIs, which also can improve consistency when errors are reported.
Service Loader Mediator
The Java Service Loader was a flawed implementation of a generic service loader mechanism; by design it operates only on a single ClassLoader and provides a static binding to objects that it returns. Since OSGi works with multiple ClassLoaders and deals with dynamic resolution, the Service Loader must be fixed.
The Service Loader Mediator provides such a fix, by enabling a mechanism such as byte-code weaving to replace calls to the Java Service Loader with an appropriate wrapper that understands multiple class loaders. By inspecting bundles which need to have the service loader enabled, the code can reduce the amount of work that needs to be done ahead of time and allows existing JARs to use the Java package. By adding OSGi attributes to the manifest, and therefore opting in to the service loader mediator processing, bundles can be upgraded in situ without needing significant rework.
The mediator can also be used to publish services as OSGi services, that can be consumed by clients elsewhere in the runtime.
OSGi subsystems allows a single OSGi runtime to host multiple partitions of applications. This allows an application to define an exact bundle dependency (such as log4j 1.2.14) whilst another application in the same OSGi framework (but different subsystem) could be bound to a different version (such as log4j 1.2.16).
Subsystems are the result of a long investigation in OSGi to allow multiple applications to run but in a partitioned way. Previously known as Composite Bundles or Nested Frameworks, the purpose of Subsystems is a generification of the requirements to be able to run multiple bundles in one place. OSGi Release 5 is the first time this has been specified; all other iterations have been at the RFC level.
Eclipse Equinox has implemented past versions of the nested framework story; these are due to be removed in Luna as the specification was only a work in progress. On the other hand, Eclipse Virgo has been one of the key proving ground areas for such composite systems, providing as it does a 'user region' and a 'kernel region' (largely to separate out potential dependency clashes with the spring framework, which features heavily in Virgo's design).
The requirement-capability model of OSGi 5 is built upon the idea of a set of namespaced requirements. These include things like a
bundle-symbolic-name as strings that can be used to provide additional constraints. It's unlikely that most users will need to know about this, as it's really a glue specification that's used by the repository and resolver services.
The OSGi Compendium is a placeholder for everything that doesn't fit in the Core or specific vertical specs such as Enterprise or Residential. These are published as groups of services once every year or two, and represents a cut of the final specifications at that time. With the review period opening up, it may be that these specifications are delivered more iteratively in future. Ironically for an organisation based on modularity, many of the specification documents are giant aggregations of diverse APIs that evolve at different speeds; many (such as the HttpService) have remained unchanged throughout many of the past releases, yet still get repeated in text each year with the compendium documentation.
Cloud providers – especially those vested in the Eclipse Virgo platform or other highly modular environments – will be attracted to the subsystems specification, which is new for this release. The repository specification may be of interest to those currently using OBR, but it's unlikely that P2 will move towards the generic repository service at least for the next couple of releases. What will benefit all is the Service Loader Mediator, which attempts to fix problems of Java's lack of classloader support in the Service Loader API.