@Override
public Object addingBundle(Bundle bundle, BundleEvent event) {
+ if(event != null && (event.getType() == BundleEvent.STOPPED || event.getType() == BundleEvent.STOPPING)) {
+ // We're tracking RESOLVED, STARTING, and ACTIVE states but not STOPPING. So when a bundle transitions
+ // to STOPPING, removedBundle gets called and we remove the ModuleFactory entries. However the
+ // bundle will then transition to RESOLVED which will cause the tracker to notify addingBundle.
+ // In this case we don't want to re-add the ModuleFactory entries so we check if the BundleEvent
+ // is STOPPED.
+ return null;
+ }
+
URL resource = bundle.getEntry("META-INF/services/" + ModuleFactory.class.getName());
LOG.trace("Got addingBundle event of bundle {}, resource {}, event {}",
bundle, resource, event);
@Override
public void removedBundle(Bundle bundle, BundleEvent event, Object object) {
- bundleModuleFactoryMap.removeAll(new BundleKey(bundle));
+ synchronized (bundleModuleFactoryMap) {
+ bundleModuleFactoryMap.removeAll(new BundleKey(bundle));
+ }
// workaround for service tracker not getting removed service event
blankTransactionServiceTracker.blankTransaction();
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import java.util.Collection;
public void testBundleAddAndRemove() throws Exception {
final ModuleFactoryBundleTracker tracker = new ModuleFactoryBundleTracker(blankTxTracker);
doReturn(getClass().getResource("/module-factories/module-factory-ok")).when(bundle).getEntry(anyString());
- tracker.addingBundle(bundle, mock(BundleEvent.class));
+ tracker.addingBundle(bundle, null);
Collection<Entry<ModuleFactory, BundleContext>> entries = tracker.getModuleFactoryEntries();
assertNotNull(entries);
doNothing().when(blankTxTracker).blankTransaction();;
- tracker.removedBundle(bundle, mock(BundleEvent.class), bundle);
+ BundleEvent mockEvent = mock(BundleEvent.class);
+ doReturn(BundleEvent.STOPPING).when(mockEvent).getType();
+
+ tracker.removedBundle(bundle, mockEvent, bundle);
entries = tracker.getModuleFactoryEntries();
assertNotNull(entries);
assertEquals(0, entries.size());
- verify(blankTxTracker).blankTransaction();;
+ verify(blankTxTracker).blankTransaction();
+
+ reset(mockEvent);
+ doReturn(BundleEvent.STOPPED).when(mockEvent).getType();
+
+ tracker.addingBundle(bundle, mockEvent);
+
+ assertEquals(0, tracker.getModuleFactoryEntries().size());
}
@Test