New Features for the Framework
What’s New in Core 4.3? - Part 2
Start Level API
The StartLevel framework service was introduced by Release 3 in 2003. Like the PackageAdmin service, it was also provided as a framework service as a way to add function to the Framework that could be optional and not complicate the core types. But this design, like PackageAdmin, was not very object oriented.
In 4.3, with the introduction of the adapt method to Bundle, we introduce the new Start Level API which replaces the StartLevel framework service. To inspect or modify the start level information for a bundle, the bundle can be adapted to the BundleStartLevel type. To inspect or modify the start level information for the Framework, the system bundle can be adapted to the FrameworkStartLevel type (Figure 5).
While StartLevel has been deprecated and replaced by the Start Level API, framework implementations will still implement the StartLevel service for some time to come to support existing bundles that use the StartLevel service.
Bytecode weaving is becoming very popular particularly in enterprise applications such as those using JPA. There has long been interest in bytecode weaving in OSGi but there has never been an OSGi standard way to do it. In 4.3, we introduce Weaving Hooks.
Weaving Hooks are services registered by bundles that are prepared to weave the class files loaded from other bundles. Whenever the Framework is preparing to load a class from a bundle, it first calls the weaving hooks to give them an opportunity to mutate the class file for the class. The Framework will create a WovenClass object for the class being loaded and call the WeavingHook services in service ranking order.
Each weaving hook will have the opportunity to mutate the byte array containing the class file of the class to be loaded. Since it is quite common for a weaver to add code which may call classes which are not originally used by the bundle, for example, tracing or logging APIs, the weaver needs to be able to modify the woven bundle’s wiring so the bundle can access these classes. So the WovenClass object lets the weaving hook add DynamicImport-Package entries to the bundle’s wiring. These entries can refer to the packages which contain the classes used by the newly woven class. Once all the weaving hooks have been called, the Framework will put the new DynamicImport-Package entries into effect and call the VM to define the woven class (Figure 6).
Since weaving hooks can modify classes from other bundles, care must be taken in developing and deploying weaver bundles to ensure the integrity and security of the system.
In previously released drafts for Core 4.3, there were specification proposals for Composite Bundles and virtual frameworks. These proposals were attempts at defining a grouping model for bundles such that bundles in a group would be able to share packages and services while bundles outside the group would have more limited access.
Both of these design proposals have been replaced in the final Core 4.3 specification with the introduction of Resolver Hooks and Bundle Hooks. The Resolver Hooks, along with Bundle Hooks and Service Hooks, provide low level primitives upon which grouping policies for bundles can be implemented. Using these hooks allows different grouping policies to be created rather than specifying a single grouping policy into the Framework.
A ResolverHookFactory is a service that is registered by bundles that wish to influence the Framework’s resolver and how it wires bundles together. For each resolve operation, the Framework will call the ResolverHookFactory services, in service ranking order, requesting a ResolverHook object that will be used for the duration of the resolve operation. Each resolver hook object will be called and given the opportunity to influence the resolve operation by restricting the bundles that can be resolved and which candidate capabilities can be used to satisfy a requirement (Figure 7).
So, while a resolver hook can’t actually make the decisions about how the bundles are wired together, it can influence the choices the resolver can make. This allows a resolver hook to create a grouping policy for bundles with respect to how the bundles can be wired. Using the new Resolver Hooks, the Service Hooks introduced by 4.2, and the new Bundle Hooks, a complete grouping model can be implemented.
Since resolver hooks can modify how, and even if, bundles are resolved, care must be taken in developing and deploying resolver hooks to ensure the integrity and reliability of the system.
The Service Hooks introduced by 4.2 and the new Resolver Hooks are important parts of implementing a grouping policy for bundles. With Resolver Hooks you can place limits on how bundles are wired together at resolve time. With Service Hooks you can place limits on what services are visible to a bundle. The missing piece is how to limit which bundles are visible to a bundle. This is the purpose of the newly introduced Bundle Hooks.
Bundle Hooks are services registered by bundles that are called by the Framework, in service ranking order, when the Framework must decide whether a bundle can observe another bundle. Two bundle hooks are defined. The Find Hooks are called by the Framework during the processing of the getBundle(long) and getBundles() methods of Bundle-Context. These methods are used by bundles to find other bundles. A FindHook is able to remove bundles from the result set thus preventing the calling bundle from observing the removed bundles.
The other bundle hook is the Event Hook. The Event Hooks are called by the Framework during the delivery of Bundle Events. An EventHook can remove bundles from the set of bundles whose listeners would receive the bundle event. This prevents the removed bundles from observing the Bundle Event (Figure 8).
Bundle Hook implementations must take care to ensure that bundles consistently observe or don’t observe other bundles. That is, with the Event Hook, a bundle should see either all or none of the life cycle events for a bundle. Seeing only a partial set of events can result in undefined behavior for the observing bundle.
Version 4.3 of the Core specification is another incremental improvement over past specifications. The basic abstractions of OSGi: modularity, dynamic life cycle and services, all continue as before. These new features add to the level of introspection and control of the Framework.
Some of the new features enable new and powerful capabilities to be built upon the Framework. Take care if you decide to use these low level features since they can have a significant effect on other bundles.
At the OSGi Alliance, we are continuing to work on new specifications and enhancements to the existing specifications. If you have input or want to participate in the effort, please check out the OSGi Alliance website for information on joining the OSGi Alliance or providing feedback.
- Capabilities and Requirements
- Start Level API