Dienstag, 25. Oktober 2011

OSGi - How to get the Bundle Context in a Java Object Instance

In most cases I use DS components, when I need the bundle context instance, the DS Framework injects me the bundle context in the activation method of my component. In most components I don’t like to have a dependency on OSGi APIs in my DS components, but thats another topic.

But sometimes I need an OSGi service or the BundleContext also in non OSGi / DS controlled class. E.g. when I like to write a JAX-WS web service class. There are many ways to get the Bundle Context into this type of Objects. One is to get the Bundle Context from the ClassLoader (which should implements the BundleReference interface). Here a short demo code snippet how to get the bundle API and also the bundle context of a class.



Comment: "However, this requires the code to have the permission to access the class loader." OSGi Core Specification see section 3.8.9.

Better implementation (thanks at Holger for the hint) is by using the OSGi FrameworkUtil class. See the second code snippet:



Another solution could be a holder class with a static field, which holds the actual bundle context instance. This also works when the code does not have the permission to access the class loader.

Kommentare:

  1. Also see: http://www.osgi.org/javadoc/r4v43/org/osgi/framework/FrameworkUtil.html#getBundle%28java.lang.Class%29 :-)

    AntwortenLöschen
  2. Thanks for the hint, will add a second code snippet to the post with FrameworkUtil.getBundle(MyDemoClass.class);

    AntwortenLöschen
  3. Hi Christian,

    I have just tested both examples above but I receive a java.lang.NullPointerException. I found that Bundle value is null as below:
    Bundle bd = FrameworkUtil.getBundle(SimpleCapture.class); // return null

    Could you give me idea to solve this problem?

    Thank,

    Thuy

    AntwortenLöschen
    Antworten
    1. @Thuy, can you give me a little bit more information? Can I find the source of your bundle anywhere?
      From where do you call the FrameworkUtil class inside a bundle?

      Löschen
    2. Hi Christian,
      The below code is used to verify Bundle object returned by getBundle(...) is null:
      -----------------------------------------------
      public static MediaService getMediaService()
      {
      if (mediaService == null)
      {
      bd = FrameworkUtil.getBundle(SimpleCapture.class); // return null
      bundleContext = bd.getBundleContext();

      mediaService = ServiceUtils.getService(bundleContext, MediaService.class);
      }
      return mediaService;
      }

      -----------------------------------------------

      Thanks

      Thuy

      Löschen
  4. Hi Christian,

    May I send you my sample code? This is my email address n_huythuybk(at)yahoo(dot)com, please give me your email if possible. Below is my test code which is extracted from my testing program:

    -----------------------------------------
    public class SimpleCapture implements java.beans.PropertyChangeListener {

    private MediaDevice md;
    private List listMediaDevices;
    private List mf;
    private static MediaService mediaService;
    private static BundleContext bundleContext;
    private static Bundle bd;

    private DSCapture graph;

    public static MediaService getMediaService()
    {
    if (mediaService == null)
    {
    BundleContext bc = FrameworkUtil.getBundle(SimpleCapture.class).getBundleContext();
    bd = FrameworkUtil.getBundle(SimpleCapture.class);
    bundleContext = bd.getBundleContext();

    mediaService = ServiceUtils.getService(bundleContext, MediaService.class);
    }
    return mediaService;
    }

    public SimpleCapture() {
    MediaType mediaType = MediaType.VIDEO;

    listMediaDevices = getMediaService().getDevices(mediaType, MediaUseCase.ANY);
    //md = getDefaultDevice(mediaType);
    mf = md.getSupportedFormats();

    }

    ...
    }
    -----------------------------------------

    Thanks

    Thuy

    AntwortenLöschen