2.1.3 Dynamism with OSGi

Beyond modularity, OSGi, through its history of development for embedded devices, is built around dynamism from the core. For embedded devices, updates often must be performed live and the whole system must be able to cope with a bundle disappearing and then reappearing or even being present and active more than once for a certain interval.

The same features are also important in other areas, such as for minimizing the downtime of server-side applications. However, the dynamism features of OSGi have been far less exploited than the modularity features. No doubt this situation is due to the inherent complexity in building applications that can deal well with dynamics, a topic that is much less understood than modularity.

All artifacts in OSGi are equipped with the support of dynamics in the form of defined life cycles (OSGi core specification on page 119). The life cycle of a bundle is much closer to that of a JEE application than that of a plain JAR file, which only exists on the class path. First of all, a bundle is installed into an OSGi runtime environment, which is called the OSGi framework, at a certain point in time. A bundle that is installed is known to the framework but otherwise useless. A bundle, whose dependencies can all be satisfied, next moves to the resolved state. Usually, a bundle will further transition to active state either when any class from the bundle is loaded or when an external agent starts the bundle. At the end of its life, a bundle can be uninstalled from the framework again. However, when uninstalling a bundle, OSGi ensures that any packages, which the bundle provides to other still resolved or active bundles, remain available.

Figure 2-4 Bundle life cycle states (non-relevant transitions omitted)

When a bundle moves to the active state, the OSGi framework optionally invokes a special class, called the bundle activator, which is specified in the bundle manifest. The bundle activator allows an OSGi bundle to be more than just a provider of classes, but actively to execute tasks, register and consume services, and so forth. Application developers must use blueprint in preference to bundle activators wherever possible.

Finally, that OSGi is built with support for convenience. Bundles are not started unnecessarily but only when explicitly requested or first needed. Even when started explicitly, a bundle author can defer activation to when the first class is loaded from the bundle, which is called lazy activation.

As an immediate consequence of bundles having life cycles, services must also have life cycles. The life cycle of a service, by default, is framed by the life cycle of the bundle that provides it. However, bundles can choose to dynamically publish and retract services due to changes in the environment, for example, due to one required service going away or coming back.

Bundle and service life cycles, along with the event notification support that OSGi defines around them, give developers the tools to build truly dynamic applications. However, even with this support, it is not trivial to write code that can cope appropriately with a truly dynamic environment in which services can come and go at any time.

We describe OSGi dynamics and how to exploit them further in 6.3, Exploiting OSGi dynamics.

Copyright IBM Corp. 2010. All rights reserved.