Uploaded image for project: 'Felix'
  1. Felix
  2. FELIX-6162

ConfigurationManager crashes on shutdown if PersistenceManager not yet available

    XMLWordPrintableJSON

Details

    Description

      If ConfigurationManager shuts down, it tries to close the managedServiceFactoryTracker and managedServiceTracker.

      ConfigurationManager.stop():

              // stop handling ManagedService[Factory] services
              managedServiceFactoryTracker.close();
              managedServiceTracker.close();
      

      In integration tests both services might not available at this time and it crashes:

      java.lang.NullPointerException
                   at org.apache.felix.cm.impl.ConfigurationManager.stop(ConfigurationManager.java:222)
                   at org.apache.felix.cm.impl.ConfigurationAdminStarter.deactivate(ConfigurationAdminStarter.java:95)
                   at org.apache.felix.cm.impl.DependencyTracker.stop(DependencyTracker.java:112)
                   at org.apache.felix.cm.impl.Activator.stop(Activator.java:160)
                   at org.apache.felix.framework.util.SecureAction.stopActivator(SecureAction.java:720)
                   at org.apache.felix.framework.Felix.stopBundle(Felix.java:2795)
      
      

      ++

                   at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1557)
                   at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:308)
                   at java.lang.Thread.run(Thread.java:748)
      

      The reason for this is that managedServiceTracker and managedServiceFactoryTracker are assigned after service registration of ConfigurationAdmin in the start() method.
      The integration test is (sometimes) directly run after the bundleContext.registerService(ConfigurationAdmin.class, ...) line. And directly after the integration test execution the Configuration.stop() method is called where it crashes as managedServiceTracker and managedServiceFactoryTracker are still null.

      ConfigurationManager.start():

              configurationAdminRegistration = bundleContext.registerService(ConfigurationAdmin.class, caf,
                      serviceProperties);
      
              // start handling ManagedService[Factory] services
              managedServiceTracker = new ManagedServiceTracker(this);
              managedServiceFactoryTracker = new ManagedServiceFactoryTracker(this);
      

      Although this sounds like a rare race-condition, it is reproducible in our test environment. About 30% of the tests fail with the above exception.

      A simple solution would be to just add null-checks (as with every other service that is accessed in the stop() method):
      ConfigurationManager.stop():

              // stop handling ManagedService[Factory] services
              if (managedServiceFactoryTracker != null)
              {
                  managedServiceFactoryTracker.close();
              }
              if (managedServiceTracker != null)
              {
                  managedServiceTracker.close();
              }
      

      Attachments

        Activity

          People

            cziegeler Carsten Ziegeler
            tobgun Tobias Gunkel
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: