A Bundle That Stops Itself
In certain cases it is necessary for a bundle to stop itself. This should be done with care because the stop method will then return to a bundle that has just be stopped. The issue is more extensively explained in Best Practice with Depressed Bundles.
Purpose
Bundles that want to stop themselves without causing havoc.
Prerequisites
- osgi interfaces, provides all service interfaces for the OSGi specifications.
Instructions
The demonstration program is quite simple. The activator creates a thread. The thread does some work and at the end of the work it calls the @@safeStop()@ method. This method runs the stop method in another thread. This thread waits until the main thread has finished and then calls stop. This guarantees that the main thread is done and the amount of code executed in the bundle after it is stopped is absolutely minimal.
The source code looks as follows:
package aQute.stop; import org.osgi.framework.*; public class DepressedActivator extends Thread implements BundleActivator { BundleContext context; boolean quit; public void start(BundleContext context) throws Exception { System.out.println("start {"); this.context = context; start(); System.out.println("start }"); } public synchronized void stop(BundleContext context) throws Exception { System.out.println("stop {"); quit = true; interrupt(); System.out.println("stop }"); } public void run() { System.out.println("run {"); // Do something really interesting safeStop(); System.out.println("run }"); } public synchronized void safeStop() { System.out.println("safeStop {"); if (quit) { System.out .println(" safeStop } (after early return)"); return; } final Thread activator = this; new Thread() { public void run() { System.out .println("safeStop.run {"); try { try { activator.join(10000); System.out .println("joined"); } catch (InterruptedException e) { // Ignore this silly exception } context.getBundle().stop(); } catch (BundleException e) { e.printStackTrace(); } System.out .println("safeStop.run }"); } }.start(); System.out.println("safeStop }"); } }
The code is heavily sprinkled with print statements to follow the actions. What will happen when you run this code?
start {
start }
run {
safeStop {
safeStop }
run }
safeStop.run {
joined
stop {
stop }
safeStop.run }



