Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
None
-
None
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(); }