OSGi Release 6 Specifications add Data Transfer Objects and Versioning Annotations
At last month's OSGi DevCon in New York, the OSGi Alliance released OSGi Core Release 6. This maintains backward compatibility with 2012's OSGi R5, and is implemented in Equinox as part of Eclipse Luna.
The specification lists the changes of what's new, as well as some minor changes adds two new capabilities:
Data Transfer Objects provide a means of representing the state of objects inside an OSGi framework.
Versioning Annotations for declaring the package version and whether interfaces are consumers or producers.
Native Namespace provides a standard
osgi.native namespace for the generic
Extension BundleActivators have been added to allow bundles to participate in framework startup and shutdown
The Data Transfer Objects are rooted with the
org.osgi.dto.DTO class. Each subclass has a number of public attributes mapping onto the underlying OSGi object. The intent of the objects are to take a snapshot of the state of the system in a provider-independent way so that the data can be serialised across a network to a remote location. Accessing the DTO is done by calling adapt() on the underlying framework object with the name of the required DTO type:
BundleDTO bdto = bundle.adapt(BundleDTO.class).
Unfortunately despite being a data object, the DTO class is not serialisable, so it cannot be used with standard Java serialisation methods. However, libraries like GSon can be used to convert the data object into a form that can be sent over the network. There is an underspecified
toString method which may provide a means to debug the object's content, but cannot be used for interoperability. However, it is likely that remote management interfaces will take advantage of the DTO specification to acquire the state of a remote OSGi framework and present it via a user interface.
The DTO instances are intended to be a read-only snapshot; there are no methods or ways of manipulating the framework based on the state of changes.
The versioning annotations provide a means to identify if an interface is intended to be used by clients or implemented by clients. Interfaces annotated with
@ProviderType are expected to be used by clients, but not implement them – equivalent to the
@noimplement used by Eclipse. Interfaces annotated with the
@ConsumerType are intended to be implemented by clients.
Tools can read these annotations (which are retained in the class files but not used at run-time) and provide warning or error information based on the semantic version numbering. Adding methods to interfaces that are annotated with
@ProviderType require updating the package or bundle's minor number, since it is backward compatible; however, adding methods to interfaces annotated with
@ConsumerType are breaking changes which require the major version number to be incremented.
An additional annotation,
@Version, is also specified in the package which is retained at the package level (for use in
package-info files) that can be processed by tools to generate the appropriate version number information.
The annotations are provided by a standalone JAR file,
osgi.annotations, rather than the core framework itself. As a result, code that wishes to use these annotations in code must add an additional JAR instead of using a core framework implementation. Since the annotations JAR is not a bundle (it has no
Export-Package header in the
META-INF/MANIFEST.MF file) it cannot be resolved in classes using PDE build that use package names to wire up dependencies. Instead it has to be added as a classpath dependency, or checked into the repository like the equinox framework does. At the time of writing, the OSGi JARs are not available in Eclipse Luna, so Eclipse users are likely to continue using the
@noimplement JavaDoc tag.
osgi.native namespace provides a means to encode
Provide-Capability elements within a bundle so that dependencies can be wired up correctly. This doesn't replace the
Bundle-NativeCode header; however, the framework converts the constraints specified in the
Bundle-NativeCode to a set of
osgi.native requirements and provisions.
The framework has added the notion of an
ExtensionBundle-Activator. This allows a bundle to hook into framework startup and shutdown, provided that it is declared as a framework extension (with
Fragment-Host: system.bundle;extension:=framework). This implements the standard
BundleActivator interface, but is specifically for framework extensions.
The OSGi Core Release 6 also adds some minor changes to existing objects; the
Framework class gains an
init method taking a variable number of
FrameworkWiring adds a new
findProviders method and a new
WovenClassListener has been added to the weaving hooks.
For more information about the OSGi Core Release 6, see the specifications on the OSGi website. The OSGi Alliance are also working on a toolchain called En Route; InfoQ recently interviewed Peter Kriens about it