4

I've stumbled upon a problem, that can be summarized as follows:

I have an application which is embedded with OSGI. In this OSGI container, I have installed a bundle A of version v1 which registers that service object. This service object is used by the host application. while the service object is in use, I uninstalled the bundle A and installed a new version(v2) of the bundle A. Here are my findings.

  • Old service object works fine even if we uninstall the bundle A(v1).
  • The new service object gives the new functionality of bundle A(v2).

My question here is when we refresh the bundle packages by using

List<Bundle> refreshbundles = new ArrayList<Bundle>();
Bundle local; // points to the bundle
refreshbundles.add(local);
m_felix.adapt(FrameworkWiring.class).refreshBundles(refreshbundles)

and when we try to get the service object registered by the new version of the bundle A, it is returning null. I tried looking at the source code but it didn't help. can you please help me with this?

EDIT:

HostApplication

public Felix m_felix = null;
m_felix = new Felix(config); //sending some config to felix.
m_felix.start();

//installing bundle
Bundle bundle = m_felix.getBundleContext().installBundle("file:/bundleA-1.0.jar")    
bundle.start()

//getting the service object registered by bundle A.
ServiceReference sr = m_felix.getBundleContext()
                        .getServiceReference(SampleInterface.class.getName()))
(SampleInterface) m_felix.getBundleContext(sr).getService().sayHI();

//now uninstalling the bundle installing the new version of it say version 1.1
bundle.uninstall()
bundle = m_felix.getBundleContext().installBundle("file:/bundleA-1.1.jar")    
bundle.start()

//getting the service object registered by bundleA1.1

ServiceReference sr = m_felix.getBundleContext()
                    .getServiceReference(SampleInterface.class.getName()))
(SampleInterface) m_felix.getBundleContext(sr).getService().sayHI();

//the above line is working fine but after refreshing the packages, Service object is returned as null    

List<Bundle> refreshbundles = new ArrayList<Bundle>();
Bundle bundle; // points to the bundle
refreshbundles.add(bundle);
m_felix.adapt(FrameworkWiring.class).refreshBundles(refreshbundles)

//refresh done
ServiceReference sr = m_felix.getBundleContext()
                    .getServiceReference(SampleInterface.class.getName()))
(SampleInterface) m_felix.getBundleContext(sr).getService().sayHI();

//throwing null pointer exception because getService() is returning null.

what exactly is happening when we refresh the bundles?

BundleA_Activator.java

public class BundleA_Activator extends BundleActivator{
   public class BundleActivatorInterfaces implements  BundleActivator{
    ServiceRegistration SR;
    @Override
    public void start(BundleContext bundleContext) {

        SR = bundleContext.registerService(SampleInterface.class.getName(), new ExposedClass(), null);
    }

    @Override
    public void stop(BundleContext bundleContext) {
            SR.unregister();
    }
}
imcat
  • 158
  • 6
  • Which bundle exports the service interface? Is it the same bundle registers the service? From which bundle are you looking for the service? Which bundle did you refresh in the code above? How are you looking for the service (code please)? – Neil Bartlett Nov 23 '18 at 14:55
  • As it is embedded OSGI I'm looking for service from host application in which OSGI is started. I hope the above code will answer the others questions. thank you. If you have any other questions please comment. – imcat Nov 25 '18 at 06:18
  • Is the package containing SampleInterface exported by the system bundle and imported by bundleA? Also, what is the state of bundleA after you call refresh? – Neil Bartlett Nov 26 '18 at 09:40
  • Thank you neil. SampleInterface is added as SYSTEM_PACKAGE in Host Application and it is imported by Bundle A. State of bundle A is Active. So, I started the bundle again which solved my issue. Refreshing bundles is changing the state of the bundle from Active to Resolve by calling bundle.stop(). – imcat Nov 27 '18 at 06:29
  • 2
    Aha, so the bundle was not publishing the service because it was not ACTIVE. Good job finding the issue. However there are some problems with the code you posted. One is that you call `getService` several times but never call `ungetService`, so the service cannot be released by OSGi. – Neil Bartlett Nov 27 '18 at 10:03
  • Thank you @NeilBartlett for the suggestion. – imcat Nov 27 '18 at 10:21

0 Answers0