Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update OSGi bundle while starting

Tags:

osgi

I have several OSGi bundles, each of which can be updated from an OSGi Bundle Repository. When I start my OSGi framework (Apache Felix), I want the first bundle to start and check for updates for all installed bundles. If updates are available, it should update each of them (including itself) then continue starting (or possibly shutdown, and the OS will restart the app).

How is this best done in an OSGi compliant manner?

How should the first bundle update itself? Can it update itself while it is starting?

like image 893
Philipp Avatar asked Oct 07 '10 14:10

Philipp


People also ask

What is OSGi start level?

A start level is simply a non-negative integer value. The Framework has an ‚active start level' that is used to decide which bundles can be started. Bundles themselves have an associated ‚bundle start level' which is used to determine when a bundle is started.

What is the difference between OSGi bundle and Java package?

The key difference with OSGi is that a JAR is now all private, adding metadata in the manifest makes it a bundle that can safely share with other bundles. OSGi makes sure violations are detected ahead of time. So, can a bundle be used in place of a jar in a JavaEE application? yes, it is a normal JAR.


2 Answers

There are a couple of things you should do:

  1. Make sure you have one bundle (the "management agent" as it is often called in the spec) that starts first on framework (re)starts by giving it a lower start level than all your other bundles. Also make sure you tell the system to start with a start level equal to that of the management agent. That way this bundle will be able to update all other bundles in the framework before they actually get started. Only after the management agent is done updating will it refresh all packages and go to the next start level, effectively starting all other bundles.

  2. To update the management agent, the best way is to temporarily install a second bundle that actually performs the update. Spawning threads within the management agent is not the best solution, as those threads should not keep running once the bundle is stopped and not complying with that might give you problems that are hard to solve. That second bundle will actually update and maybe even rollback if the update fails.

An example of a management agent that can update itself can be found as part of the Apache ACE. It has an agent that will, from code, install a second bundle to update itself from a remote location. Some pointers to relevant parts of that project:

  • http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentUpdateHandlerImpl.java?view=markup for the code that installs the temporary bundle
  • http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/updater/Activator.java?view=markup for the activator of the temporary bundle
  • http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/ for the bnd project of the agent itself
like image 183
Marcel Offermans Avatar answered Sep 21 '22 06:09

Marcel Offermans


You may have a look at the state diagram in the OSGi Core Spec (this should be Fig.28). There you can see that a bundle in STARTING state can only move to ACTIVE state (with the exception when an exception is thrown). A bundle can only be updated when it is either in INSTALLED or RESOLVED state. For this it must be stopped in case it is in ACTIVE state.

The problem here is that you cannot stop a bundle when it is in STARTING state. And as long as the Activators start() method is executed the bundle is still in STARTING state, not ACTIVE.

What you can do is to start a thread in the Bundle that checks its state for ACTIVE and then call the update() method. But don't forget to terminate the thread, otherwise the garbage collector cannot free the resources of the current bundle's jar file.

like image 24
Andreas Kraft Avatar answered Sep 18 '22 06:09

Andreas Kraft