You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by jw...@apache.org on 2012/11/21 17:31:11 UTC

svn commit: r1412179 - in /aries/trunk/subsystem: subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/

Author: jwross
Date: Wed Nov 21 16:31:10 2012
New Revision: 1412179

URL: http://svn.apache.org/viewvc?rev=1412179&view=rev
Log:
[ARIES-967] NPE in org.apache.aries.subsystem.core.internal.BundleEventHook.event() at server shutdown.

Updated the bundle event hook to handle the case where it receives an uninstalled event for a bundle that is not in its
internal data structure because the hook was not registered when the bundle was installed.

Also fixed another issue where region context bundles of subsystems that failed to install at certain points were not
being uninstalled.

Added some new tests highlighting unmanaged bundle behavior.

Modified:
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleEventHook.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleResourceInstaller.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceInstaller.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Subsystems.java
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/UnmanagedBundleTest.java

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleEventHook.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleEventHook.java?rev=1412179&r1=1412178&r2=1412179&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleEventHook.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleEventHook.java Wed Nov 21 16:31:10 2012
@@ -93,12 +93,24 @@ public class BundleEventHook implements 
 			handleExplicitlyInstalledBundleBundleContext(originRevision, bundleRevision);
 	}
 	
+	@SuppressWarnings("unchecked")
 	private void handleUninstalledEvent(BundleEvent event) {
 		Bundle bundle = event.getBundle();
 		BundleRevision revision = bundleToRevision.remove(bundle);
 		if (ThreadLocalSubsystem.get() != null)
 			return;
-		for (BasicSubsystem subsystem : Activator.getInstance().getSubsystems().getSubsystemsByConstituent(new BundleConstituent(null, revision)))
+		Collection<BasicSubsystem> subsystems;
+		if (revision == null) {
+			// The bundle was installed while the bundle event hook was unregistered.
+			Object[] o = Activator.getInstance().getSubsystems().getSubsystemsByBundle(bundle);
+			if (o == null)
+				return;
+			revision = (BundleRevision)o[0];
+			subsystems = (Collection<BasicSubsystem>)o[1];
+		}
+		else
+			subsystems = Activator.getInstance().getSubsystems().getSubsystemsByConstituent(new BundleConstituent(null, revision));
+		for (BasicSubsystem subsystem : subsystems)
 			ResourceUninstaller.newInstance(revision, subsystem).uninstall();
 	}
 }

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleResourceInstaller.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleResourceInstaller.java?rev=1412179&r1=1412178&r2=1412179&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleResourceInstaller.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleResourceInstaller.java Wed Nov 21 16:31:10 2012
@@ -108,6 +108,14 @@ public class BundleResourceInstaller ext
 		public Bundle getBundle() {
 			return revision.getBundle();
 		}
+		
+		public Resource getResource() {
+			return resource;
+		}
+		
+		public BundleRevision getRevision() {
+			return revision;
+		}
 
 		@Override
 		public String getSymbolicName() {

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceInstaller.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceInstaller.java?rev=1412179&r1=1412178&r2=1412179&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceInstaller.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceInstaller.java Wed Nov 21 16:31:10 2012
@@ -13,12 +13,14 @@
  */
 package org.apache.aries.subsystem.core.internal;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 
 import org.apache.aries.util.filesystem.FileSystem;
+import org.osgi.framework.BundleException;
 import org.osgi.resource.Resource;
 import org.osgi.service.coordinator.Coordination;
 import org.osgi.service.coordinator.Participant;
@@ -90,8 +92,7 @@ public class SubsystemResourceInstaller 
 		addReference(subsystem);
 		addConstituent(subsystem);
 		addSubsystem(subsystem);
-		if (subsystem.isScoped())
-			RegionContextBundleHelper.installRegionContextBundle(subsystem);
+		installRegionContextBundle(subsystem);
 		Activator.getInstance().getSubsystemServiceRegistrar().register(subsystem, this.subsystem);
 		Comparator<Resource> comparator = new InstallResourceComparator();
 		// Install dependencies first...
@@ -128,6 +129,23 @@ public class SubsystemResourceInstaller 
 		return installSubsystemResource(subsystemResource);
 	}
 	
+	private void installRegionContextBundle(final BasicSubsystem subsystem) throws BundleException, IOException {
+		if (!subsystem.isScoped())
+			return;
+		RegionContextBundleHelper.installRegionContextBundle(subsystem);
+		coordination.addParticipant(new Participant() {
+			@Override
+			public void ended(Coordination coordination) throws Exception {
+				// Nothing
+			}
+
+			@Override
+			public void failed(Coordination coordination) throws Exception {
+				RegionContextBundleHelper.uninstallRegionContextBundle(subsystem);
+			}
+		});
+	}
+	
 	private BasicSubsystem installRepositoryContent(RepositoryContent resource) throws Exception {
 		RawSubsystemResource rawSubsystemResource = new RawSubsystemResource(getLocation(), FileSystem.getFSRoot(resource.getContent()));
 		return installRawSubsystemResource(rawSubsystemResource);

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Subsystems.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Subsystems.java?rev=1412179&r1=1412178&r2=1412179&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Subsystems.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Subsystems.java Wed Nov 21 16:31:10 2012
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.aries.subsystem.core.internal.BundleResourceInstaller.BundleConstituent;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.wiring.BundleRevision;
@@ -190,6 +191,27 @@ public class Subsystems {
 		return new ArrayList<BasicSubsystem>(idToSubsystem.values());
 	}
 	
+	// TODO Not very pretty. A quick fix.
+	public Object[] getSubsystemsByBundle(Bundle bundle) {
+		BundleRevision revision = null;
+		ArrayList<BasicSubsystem> result = new ArrayList<BasicSubsystem>();
+		synchronized (subsystemToConstituents) {
+			for (BasicSubsystem subsystem : subsystemToConstituents.keySet()) {
+				for (Resource constituent : getConstituents(subsystem)) {
+					if (constituent instanceof BundleConstituent &&
+							((BundleConstituent)constituent).getBundle() == bundle) {
+						result.add(subsystem);
+						revision = ((BundleConstituent)constituent).getRevision();
+					}
+				}	
+			}
+		}
+		result.trimToSize();
+		if (revision == null)
+			return null;
+		return new Object[]{revision, result};
+	}
+	
 	public Collection<BasicSubsystem> getSubsystemsByConstituent(Resource constituent) {
 		ArrayList<BasicSubsystem> result = new ArrayList<BasicSubsystem>();
 		synchronized (subsystemToConstituents) {

Modified: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/UnmanagedBundleTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/UnmanagedBundleTest.java?rev=1412179&r1=1412178&r2=1412179&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/UnmanagedBundleTest.java (original)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/UnmanagedBundleTest.java Wed Nov 21 16:31:10 2012
@@ -116,4 +116,41 @@ public class UnmanagedBundleTest extends
 			}
 		}
 	}
+	
+	/*
+	 * Test that bundles installed when the bundle event hook is unavailable
+	 * (i.e. when the subsystems core bundle is stopped) are handled properly
+	 * by the hook when uninstalled.
+	 * 
+	 * See https://issues.apache.org/jira/browse/ARIES-967.
+	 */
+	@Test
+	public void testBundleEventHook() throws Exception {
+		Bundle core = getSubsystemCoreBundle();
+		// Stop the subsystems core bundle so the bundle event hook is not registered.
+		core.stop();
+		try {
+			// Install an unmanaged bundle that will not be seen by the bundle event hook.
+			Bundle a = bundleContext.installBundle(BUNDLE_A, new FileInputStream(BUNDLE_A));
+			try {
+				// Restart the subsystems core bundle.
+				core.start();
+				// Bundle A should be detected as a constituent of the root subsystem.
+				assertConstituent(getRootSubsystem(), BUNDLE_A);
+				// Uninstall bundle A so that it is seen by the bundle event hook.
+				a.uninstall();
+				// Bundle A should no longer be a constituent of the root subsystem.
+				assertNotConstituent(getRootSubsystem(), BUNDLE_A);
+			}
+			finally {
+				uninstallSilently(a);
+			}
+		}
+		finally {
+			try {
+				core.start();
+			}
+			catch (Exception e) {}
+		}
+	}
 }