Showing posts with label Lifecycle. Show all posts
Showing posts with label Lifecycle. Show all posts

Wednesday, October 26, 2011

The Lifecycle API

1. Bundle Activator
The main entry point for a bundle to the lifecycle API is the Activator. To use one, a bundle must declare it in its manifest, and provide the activator code. The manifest entry looks like this :

Bundle-Activator: org.phoenix.mybundle.MyActivator 

Note that the activator may be imported from another bundle, or provided in the bundle classpath.

The bundle activator, as defined in the manifest of a bundle (Bundle-Activator), is the bundle's hook into the lifecycle layer. The bundle activator must implement the interface :

org.osgi.framework.BundleActivator

which defines two methods : start(BundleContext ctx) and stop(BundleContext ctx).

When a bundle is installed and started :
  • OSGi framework creates an instance of the Activator;
  • invokes the activator's start method.
When a bundle is stopped :
  • OSGi framework invokes the stop method (on the same instance of the activator, but may be in a different thread);
  • releases the activator instance.
Warnings :
  • On a restart, a new instance of the activator is created;
  • the activator stop method should undo everything that was done in the start method.
2. Bundle Context
The bundle context is provided to the bundle by the lifecycle layer. It allows the bundle to interact with the framework, access its context, modify it.... A bundle context is unique for a bundle, and is valid between the calls to the start and stop methods. A bundle's activator should not be shared with another bundle.

As exposed in the BundleContext interface listed above, the bundle context provides access to more than its owning bundle. It also allows to access other bundles, and through them to their context. Here is the Bundle interface :

The bundle ID is a runtime ID, generated by the framework. It's different from the bundle's static identifier, declared in its manifest.
The bundle location is usually an url, from which the bundle can be downloaded. But a bundle can also be loaded from an inputstream.

3. Bundle lifecycle
The schema below shows the famous bundle life cycle diagram.


Bundle and lifecycle interactions

The module layer defines bundles and uses OSGi modularity features. The lifecycle layer uses OSGi framework to manage and execute bundles. It provides bundles with a management API and a lifecycle at runtime.
Outside the application, the lifecycle layer provides operations for the bundles through the lifecycle API.
Inside, it defines how bundles accesss their execution context.

Through the lifecycle API, a management application or an administrator can install/stop/start/update/refresh bundles to modify the application configuration. Bundles themselves can use the lifecyle API to modify their own configuration.

1. Bundle cache
OSGi framework provides a persistent bundle cache, which allows to reinstall and start the bundles that were installed at shutdown on the next framework startup. It can be seen as the deployed configuration of the application.

When started, cached bundles are marked as so. When the framework is restarted, cached bundles are reinstalled, and those marked as started are automatically started.

2. Bundle properties
Through its context, a bundle can access some properties. Theses properties can be defined either in the bundle context, or in system properties.
A call to context.getProperty("foo") searches first in the bundle context properties, then in the system properties. It eventually returns null if the property could not be found.

3. Threading
The OSGi framework heavily relies on java threads. It does not manage concurrency, but offers some guarantees. For example, it guarantees that the stop() method of a bundle activator will not be called before its start() method returns.

4. Persisting bundle state
There is only one instance of a bundle's activator between the calls of its start() and stop() methods. When the bundle is restarted, a new instance is created. This means there is no way to persist a bundle state between two starts of a bundle.

To persist a state, one has the following options :
  1. store the state in a database or a file;