• No results found

OSGi [30, 127, 26, 82, 54] is a component model that enables building component-based Java applications, and running them side-by-side on the same Java Virtual Machine. The OSGi framework is a platform that provides various services to running applications, and enables installing, updating and uninstalling individual applications without restarting the platform.

4.3.1. Component Model Description

In the OSGi component model, an operation-based interface (see Definition 1.4) is represented by a Java package, where operations are Java methods defined by the classes belonging to the package. A required interface is called an imported package, and a provided interface is called an exported package.

An OSGi component is a Java object, called a bundle, and identified with a positive integer bundle ID that is unique within the running platform instance. A bundle is loaded from an archive using a dedicated Java class loader (see Section 2.2.1) that confines the bundle implementation into a separate Java name space. The archive holds meta-data describing the bundle, e.g., exported packages, imported packages, name, vendor, version, implementation entry point, etc. The implementation of a bundle is commonly provided as Java classes (see Section 2.2) included in the archive, but it can also be platform-specific machine code loaded by the Java Virtual Machine, i.e., Java native libraries. An OSGi application is merely a set of bundles, and there is no notion of composite in this component model.

In order for a bundle B1to invoke a method M2defined in a class C2belonging to a package

P2provided by a bundle B2, three conditions are necessary: (1) B2exports P2, and (2) B1

imports P2, and (3) if M2is astaticJava method, then B1calls M2via a Java reference to C2, otherwise, B1 calls M2 via a Java reference to an object of C2. If C2 is rather an interface, then B1can only call M2via a Java reference to an object implementing the interface C2. In fact, OSGi bindings are represented by Java object references.

4.3.2. Common Details of OSGi Implementations

The OSGi framework is based on Java and it is built to run multiple OSGi bundles on one Java virtual machine. This gives OSGi the ability to provide fast cross-bundle communication, and Java code isolation, and hot-swapping support.

Fast Cross-Bundle Communication. All OSGi bundles run in the same JVM inside the

same memory address space. Consequently, communication between bundles happens via local Java method invocation (local procedure calls), making cross-bundle communication as fast as internal bundle communication. OSGi avoids the expensive cost of call serialization performed by common remote procedure call technologies, e.g., RPC [118], RMI [133], Incommunicado [102].

Code Isolation. At any given time, each bundle is associated to one dedicated Java class loader that loads the classes contained inside the archive of the bundle. Based on its class loader, each bundle can define its own security policy for its classes, which defines their access to system methods and to classes of other bundles. OSGi controls the accessibility of classes loaded by the class loader of each bundle. A bundle can choose to export some of its classes, i.e., to make them accessible to other bundles. Classes that are not exported cannot be accessed from outside the bundle. This control of accessibility is possible due to the process needed to access a class in Java, which goes as follows: In order for a class C1 loaded by a class loader L1to access a class C2loaded by a class loader L2, C1must access

L2first, asking it to resolve C2. L2can forbid access to C2in order to isolate C2 from C1.

In Java, two classes with the same name, loaded from the same class file using different class loaders are considered different types, as described in Section 2.2.1. Based on this fact, OSGi can load classes inside bundles with no risks of name conflicts, as each class loader defines a

private name space, which enable each bundle to define its own version of the classes. This

is particularly useful in OSGi, because it allows loading two versions of the same bundle simultaneously This allows, for example, to upgrade a bundle and while keeping previous versions loaded in order to preserve backward compatibility.

Hot-swapping. OSGi implements hot-swapping to load, unload and update archives on

the fly. Archive loading and unloading is based on Java class loaders, which implement lazy loading, i.e., classes are loaded when they are accessed the first time. In order to update a bundle B, the following procedure is performed (see Figure 1.5):

1. OSGi creates a new class loader which loads the new version of the archive.

2. OSGi associates Bwith the new class loader, and it removes the association with the

previous class loader.

3. OSGi broadcasts a message to all bundles indicating that B was updated. Bundles

the previous version of the bundle are removed, the previous class loader becomes unreachable (see Section 2.2.2).

4. The garbage collector should remove the previous version of the bundle from memory. The updated bundle keeps using the same bundle ID as the previous version.

Each archive Ais loaded using a class loader

L. Initially, the bundle B is associated

with the class loader L1.0. Updating Bfrom

version 1.0 to version 2.0 implies creating

L2.0, then loading A2.0 using L2.0, then associating Bwith L2.0instead of L1.0.

Non-volatile memory Memory heap

Java Virtual Machine

A1.0 A2.0 L1.0 L2.0 Archives Class loading B (B,L)

Figure 1.5: OSGi bundle update.