Question

In OSGI, we can update, activate, deactivate bundles during run time.

But I didn't understand how it is possible because some other may use functionality of this bundle. Why not this happening crashes the application ?

Normally, in JVM, whenever it runs any application, it loads source class files and required Java API class files and produces the result.

Can you explain what is the basic architecture of OSGI, so that it allows above happenings.

Was it helpful?

Solution

To understand this, you need to view the two parts of the OSGi landscape: services and (Java) classes/interfaces.

Related to services, activation, deactivation and updates are handled by the contract between the client (user) and the service provider. The client must track changes to the available services and release the use of a service as soon as it is notified that the service is going to be removed. Furthermore, it can track the availability of other services to update its reference as soon as a better service becomes available. Note that the OSGi environment is a cooperative one: non-one forces the using bundle to actually release the reference to the service. Therefore, incorrect behaviour can result to unexpected results.

As such: for services, the user of the service is responsible for handling the dynamics of the availability of services.

Related to Java classes/interfaces, meaning class loading, the handling is done by the framework itself. When a bundle that provides classes to other bundles (as announced via its Export-Package manifest entry), is un-installed, the classes the bundle provided remain available to the bundles already using them. Only by implicitly telling the framework to update the wiring of classes between bundles (via a "refresh" action on the org.osgi.service.packageadmin.PackageAdmin service, normally provided via some kind of framework console), changes are made to the classes imported by a bundle. In that case the using bundle may be deactivated by the framework, re-wired to other classes provided by different bundles and activated again.

As such: for class loading, the framework will not change the initial wiring unless explicitly told to do so. For that bundles must be aware that they can be started, loaded, stopped and unloaded at any time to handle the changing context.

Maybe some scenarios make this somewhat more clear: Assume there is an interface definition Log in bundle LogInterface. This interface provides one method: logMessage(String message). Next to this definition, there is a bundle, LogProvider, providing an implementation of the interface and a bundle making use of the functionality of the interface, LogUser. The three bundles are installed and started in the OSGi framework as bundle and package versions 1.0.0. Bundle LogProvider registers the log service object in the service registry and bundle LogUser retrieves that service object and makes calls to it for logging.

Scenario 1: Assume that the LogProvider bundle is updated without changes to the interface definition, for example to not only log to the console, but also to a file. In that case the old LogProvider bundle (version 1.0.0) must be stopped and a new LogProvider bundle (1.1.0) must be installed into the framework and started. As soon as the old LogProvider bundle is stopped, the log service goes away and LogUser is notified about it (and must release the service object). After the new LogProvider bundle is started, the LogUser bundle can look up and use the new implementation provided by LogProvider bundle 1.1.0.

Scenario 2: Assume that a new method is added to the interface definition that allows the severity code to be passed. This means that next to the logMessage(String message) method, the Log interface gets a new method logMessage(int severity, String message). Since the interface changes, bundle LogInterface version 1.0.0 is un-installed and bundle LogInterface version 1.1.0 is installed and started. Of course the LogProvider bundle must change as well to provide an implementation for the new method and therefore LogProvider version 1.3.0 is installed and started.
In this case, uninstalling LogProvider 1.2.0 and starting LogProvider version 1.3.0 will not result in LogUser being able to retrieve the newly provided service. This because LogProvider 1.3.0 loads it definition of the Log interface from LogInterface bundle 1.1.0 and LogUser from LogInterface bundle 1.0.0. To update LogUser to the new interface version, a bundle refresh must be performed to the LogUser bundle. In practice, performing this "refresh" means that the LogUser bundle will be stopped, re-wired to the new LogInterface version 1.1.0 bundle and re-started.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top