aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jwr...@apache.org
Subject svn commit: r1442572 - 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/
Date Tue, 05 Feb 2013 13:12:26 GMT
Author: jwross
Date: Tue Feb  5 13:12:26 2013
New Revision: 1442572

URL: http://svn.apache.org/viewvc?rev=1442572&view=rev
Log:
Fix resolution failure due to unprocessed bundle events.

A previous fix introduced asynchronous event processing in the bundle event hook during certain,
short time intervals,
namely while the root subsystem is initializing. This fix prevents potential deadlocks. However,
it also introduced an
issue where subsystem installations can fail due to resolution errors stemming from unprocessed
bundle events when a
client performs an installation in response to a synchronous subsystem service event. A resolution
failure occurs because
there is a bundle providing the required capability but subsystems is unaware it exists due
to the unprocessed bundle
event.

This fix mitigates the issue by insuring all pending events have been processed before the
root subsystem transitions to
the STARTING state. It is not currently possible, and perhaps unnecessary, to ensure pending
events have been processed
before transitioning to the INSTALLED state without a major refactoring. To avoid these potential
resolution failures,
clients should not attempt to install subsystems until the root subsystem has achieved at
least the STARTING, and
ideally ACTIVE, states.

Modified:
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleEventHook.java
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.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/Activator.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java?rev=1442572&r1=1442571&r2=1442572&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java
(original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java
Tue Feb  5 13:12:26 2013
@@ -75,8 +75,8 @@ public class Activator implements Bundle
 	private volatile RegionDigraph regionDigraph;
 	private volatile Resolver resolver;
 	private ServiceTracker<?,?> serviceTracker;
-	// @GuardedBy("this")
-	private Subsystems subsystems;
+
+	private volatile Subsystems subsystems;
 	
 	private final Collection<ServiceRegistration<?>> registrations = new HashSet<ServiceRegistration<?>>();
 	private final Collection<Repository> repositories = Collections.synchronizedSet(new
HashSet<Repository>());
@@ -110,12 +110,7 @@ public class Activator implements Bundle
 		return resolver;
 	}
 	
-	/* Synchronization was introduced here to prevent conflicts between the
-	 * BundleEventHook and the activation process. The activation process
-	 * must complete the initialization of the root subsystem in order to
-	 * fully initialize the Subsystems object.
-	 */
-	public synchronized Subsystems getSubsystems() {
+	public Subsystems getSubsystems() {
 		return subsystems;
 	}
 	
@@ -154,7 +149,6 @@ public class Activator implements Bundle
 		synchronized (Activator.class) {
 			instance = Activator.this;
 		}
-		registerBundleEventHook();
 		try {
 			subsystems = new Subsystems();
 		}
@@ -164,11 +158,12 @@ public class Activator implements Bundle
 		catch (Exception e) {
 			throw new SubsystemException(e);
 		}
+		registerBundleEventHook();
 		registrations.add(bundleContext.registerService(ResolverHookFactory.class, new SubsystemResolverHookFactory(subsystems),
null));
 		registrar = new SubsystemServiceRegistrar(bundleContext);
 		BasicSubsystem root = subsystems.getRootSubsystem();
-		root.start();
 		bundleEventHook.activate();
+		root.start();
 	}
 	
 	private void deactivate() {
@@ -213,11 +208,11 @@ public class Activator implements Bundle
 				.append(org.osgi.framework.Constants.OBJECTCLASS).append('=')
 				.append(Resolver.class.getName()).append(")(")
 				.append(org.osgi.framework.Constants.OBJECTCLASS).append('=')
-        .append(Repository.class.getName()).append(")(")
+				.append(Repository.class.getName()).append(")(")
+				.append(org.osgi.framework.Constants.OBJECTCLASS).append('=')
+				.append(ModelledResourceManager.class.getName()).append(")(")
 				.append(org.osgi.framework.Constants.OBJECTCLASS).append('=')
-        .append(ModelledResourceManager.class.getName()).append(")(")
-        .append(org.osgi.framework.Constants.OBJECTCLASS).append('=')
-        .append(IDirectoryFinder.class.getName()).append("))").toString();
+				.append(IDirectoryFinder.class.getName()).append("))").toString();
 	}
 	
 	private boolean hasRequiredServices() {

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=1442572&r1=1442571&r2=1442572&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
Tue Feb  5 13:12:26 2013
@@ -33,7 +33,6 @@ public class BundleEventHook implements 
 	
 	private boolean active;
 	private List<BundleEvent> events;
-	private volatile Subsystems subsystems;
 	
 	public BundleEventHook() {
 		activator = Activator.getInstance();
@@ -78,13 +77,7 @@ public class BundleEventHook implements 
 	}
 	
 	private Subsystems getSubsystems() {
-		if (subsystems == null) {
-			synchronized (this) {
-				if (subsystems == null)
-					subsystems = activator.getSubsystems();
-			}
-		}
-		return subsystems;
+		return activator.getSubsystems();
 	}
 	
 	private void handleEvent(BundleEvent event) {

Modified: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java?rev=1442572&r1=1442571&r2=1442572&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java
(original)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java
Tue Feb  5 13:12:26 2013
@@ -718,6 +718,17 @@ public abstract class SubsystemTest exte
 		return getOsgiService(Subsystem.class);
 	}
 	
+	protected Subsystem getRootSubsystemInState(Subsystem.State state, long timeout) throws
InterruptedException {
+		Subsystem root = getRootSubsystem();
+		long now = System.currentTimeMillis();
+		long then = now + timeout;
+		while (!root.getState().equals(state) && System.currentTimeMillis() < then)
+			Thread.sleep(100);
+		if (!root.getState().equals(state))
+			fail("Root subsystem never achieved state: " + state);
+		return root;
+	}
+	
 	protected Bundle getSystemBundle() {
 		return bundleContext.getBundle(Constants.SYSTEM_BUNDLE_LOCATION);
 	}

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=1442572&r1=1442571&r2=1442572&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
Tue Feb  5 13:12:26 2013
@@ -26,6 +26,7 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.ops4j.pax.exam.junit.MavenConfiguredJUnit4TestRunner;
 import org.osgi.framework.Bundle;
+import org.osgi.service.subsystem.Subsystem;
 
 /*
  * Contains a series of tests for unmanaged bundles. An unmanaged bundle is a
@@ -59,7 +60,7 @@ public class UnmanagedBundleTest extends
 	public void testInstallWhileImplBundleActive() throws Exception {
 		Bundle a = bundleContext.installBundle(BUNDLE_A, new FileInputStream(BUNDLE_A));
 		try {
-			assertConstituent(getRootSubsystem(), BUNDLE_A);
+			assertConstituent(getRootSubsystemInState(Subsystem.State.ACTIVE, 5000L), BUNDLE_A);
 		}
 		finally {
 			uninstallSilently(a);



Mime
View raw message