aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gno...@apache.org
Subject svn commit: r1422911 - in /aries/trunk/blueprint/blueprint-core/src: main/java/org/apache/aries/blueprint/container/ test/java/org/apache/aries/blueprint/ test/java/org/apache/aries/blueprint/container/
Date Mon, 17 Dec 2012 12:48:40 GMT
Author: gnodet
Date: Mon Dec 17 12:48:38 2012
New Revision: 1422911

URL: http://svn.apache.org/viewvc?rev=1422911&view=rev
Log:
[ARIES-986] Make sure the extender receives all stopping events, even if still in the initial
tracking phase, avoid some processing in the container when it is stopping, stop containers
when the proxy manager has been lost. Add additional checks before creating the container

Modified:
    aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
    aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java
    aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/TestBlueprintContainer.java
    aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/BeanRecipeTest.java

Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java?rev=1422911&r1=1422910&r2=1422911&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
(original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
Mon Dec 17 12:48:38 2012
@@ -138,7 +138,7 @@ public class BlueprintContainerImpl 
     private Set<URI> namespaces;
     private State state = State.Unknown;
     private NamespaceHandlerSet handlerSet;
-    private boolean destroyed;
+    private final AtomicBoolean destroyed = new AtomicBoolean(false);
     private Parser parser;
     private BlueprintRepository repository;
     private ServiceRegistration registration;
@@ -151,15 +151,15 @@ public class BlueprintContainerImpl 
     private ScheduledFuture timeoutFuture;
     private final AtomicBoolean scheduled = new AtomicBoolean();
     private List<ServiceRecipe> services;
-    private AccessControlContext accessControlContext;
+    private final AccessControlContext accessControlContext;
     private final IdSpace tempRecipeIdSpace = new IdSpace();
-    private ProxyManager proxyManager;
+    private final ProxyManager proxyManager;
 
-    public BlueprintContainerImpl(BundleContext bundleContext, Bundle extenderBundle, BlueprintListener
eventDispatcher,
+    public BlueprintContainerImpl(Bundle bundle, BundleContext bundleContext, Bundle extenderBundle,
BlueprintListener eventDispatcher,
                                   NamespaceHandlerRegistry handlers, ExecutorService executor,
ScheduledExecutorService timer,
                                   List<Object> pathList, ProxyManager proxyManager)
{
+        this.bundle = bundle;
         this.bundleContext = bundleContext;
-        this.bundle = bundleContext != null ? bundleContext.getBundle() : null;
         this.extenderBundle = extenderBundle;
         this.eventDispatcher = eventDispatcher;
         this.handlers = handlers;
@@ -171,6 +171,8 @@ public class BlueprintContainerImpl 
         this.processors = new ArrayList<Processor>();
         if (System.getSecurityManager() != null) {
             this.accessControlContext = BlueprintDomainCombiner.createAccessControlContext(bundleContext);
+        } else {
+            this.accessControlContext = null;
         }
         this.proxyManager = proxyManager;
     }
@@ -233,6 +235,9 @@ public class BlueprintContainerImpl 
 
     public void reload() {
         synchronized (scheduled) {
+            if (destroyed.get()) {
+                return;
+            }
             tidyupComponents();
             this.componentDefinitionRegistry.reset();
             this.repository = null;
@@ -263,7 +268,7 @@ public class BlueprintContainerImpl 
     private void doRun() {
         try {
             for (;;) {
-                if (destroyed) {
+                if (destroyed.get()) {
                     return;
                 }
                 if (bundle.getState() != Bundle.ACTIVE && bundle.getState() != Bundle.STARTING)
{
@@ -317,6 +322,9 @@ public class BlueprintContainerImpl 
                         Runnable r = new Runnable() {
                             public void run() {
                                 synchronized (scheduled) {
+                                    if (destroyed.get()) {
+                                        return;
+                                    }
                                     Throwable t = new TimeoutException();
                                     state = State.Failed;
                                     String[] missingDependecies = getMissingDependencies();
@@ -607,6 +615,9 @@ public class BlueprintContainerImpl 
     }
 
     public void notifySatisfaction(SatisfiableRecipe satisfiable) {
+        if (destroyed.get()) {
+            return;
+        }
         LOGGER.debug("Notified satisfaction {} in bundle {}: {}",
                 new Object[] { satisfiable.getName(), bundle.getSymbolicName(), satisfiable.isSatisfied()
});
         if (state == State.Create || state == State.Created ) {
@@ -727,7 +738,7 @@ public class BlueprintContainerImpl 
     }
     
     public Object getComponentInstance(String id) throws NoSuchComponentException {
-        if (repository == null) {
+        if (repository == null || destroyed.get()) {
             throw new NoSuchComponentException(id);
         }
         try {
@@ -827,38 +838,30 @@ public class BlueprintContainerImpl 
     }
 
     public void destroy() {
-//        synchronized (scheduled) {
-            destroyed = true;
-            eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.DESTROYING,
getBundle(), getExtenderBundle()));
-            executors.shutdownNow();
-
-            cancelFutureIfPresent();
-            AriesFrameworkUtil.safeUnregisterService(registration);
-
-            unregisterServices();
-
-            if (handlerSet != null) {
-                handlerSet.removeListener(this);
-                handlerSet.destroy();
-            }
-
-            destroyComponents();
+        synchronized (scheduled) {
+            destroyed.set(true);
+        }
+        eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.DESTROYING, getBundle(),
getExtenderBundle()));
+        executors.shutdownNow();
+        if (handlerSet != null) {
+            handlerSet.removeListener(this);
+            handlerSet.destroy();
+        }
 
-            untrackServiceReferences();
+        try {
+            executors.awaitTermination(5 * 60, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            LOGGER.debug("Interrupted waiting for executor to shut down");
+        }
 
-            try {
-                executors.awaitTermination(5 * 60, TimeUnit.SECONDS);
-            } catch (InterruptedException e) {
-                LOGGER.debug("Interrupted waiting for executor to shut down");
-            }
+        tidyupComponents();
 
-            eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.DESTROYED, getBundle(),
getExtenderBundle()));
-            LOGGER.debug("Blueprint container destroyed: {}", this.bundleContext);
-//        }
+        eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.DESTROYED, getBundle(),
getExtenderBundle()));
+        LOGGER.debug("Blueprint container destroyed: {}", this.bundleContext);
     }
     
     protected void quiesce() {
-        destroyed = true;
+        destroyed.set(true);
         eventDispatcher.blueprintEvent(new BlueprintEvent(BlueprintEvent.DESTROYING, getBundle(),
getExtenderBundle()));
 
         cancelFutureIfPresent();
@@ -886,6 +889,9 @@ public class BlueprintContainerImpl 
     public void namespaceHandlerUnregistered(URI uri) {
         if (namespaces != null && namespaces.contains(uri)) {
             synchronized (scheduled) {
+                if (destroyed.get()) {
+                    return;
+                }
                 tidyupComponents();
                 this.componentDefinitionRegistry.reset();
                 this.repository = null;
@@ -897,9 +903,9 @@ public class BlueprintContainerImpl 
 
     private void tidyupComponents()
     {
+      untrackServiceReferences();
       unregisterServices();
       destroyComponents();
-      untrackServiceReferences();
     }
 
     public void injectBeanInstance(BeanMetadata bmd, Object o) 

Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java?rev=1422911&r1=1422910&r2=1422911&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java
(original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java
Mon Dec 17 12:48:38 2012
@@ -49,6 +49,7 @@ import org.osgi.framework.BundleEvent;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.SynchronousBundleListener;
 import org.osgi.service.blueprint.container.BlueprintContainer;
 import org.osgi.service.blueprint.container.BlueprintEvent;
 import org.osgi.util.tracker.BundleTrackerCustomizer;
@@ -60,7 +61,7 @@ import org.slf4j.LoggerFactory;
  *
  * @version $Rev$, $Date$
  */
-public class BlueprintExtender implements BundleActivator, BundleTrackerCustomizer {
+public class BlueprintExtender implements BundleActivator, BundleTrackerCustomizer, SynchronousBundleListener
{
 
     /** The QuiesceParticipant implementation class name */
     private static final String QUIESCE_PARTICIPANT_CLASS = "org.apache.aries.quiesce.participant.QuiesceParticipant";
@@ -92,6 +93,12 @@ public class BlueprintExtender implement
         });
         eventDispatcher = new BlueprintEventDispatcher(ctx, executors);
 
+        // Ideally we'd want to only track STARTING and ACTIVE bundle, but this is not supported
+        // when using equinox composites.  This would ensure that no STOPPING event is lost
while
+        // tracking the initial bundles. To work around this issue, we need to register
+        // a synchronous bundle listener that will ensure the stopping event will be correctly
+        // handled.
+        context.addBundleListener(this);
         int mask = Bundle.INSTALLED | Bundle.RESOLVED | Bundle.STARTING | Bundle.STOPPING
| Bundle.ACTIVE;
         bt = new RecursiveBundleTracker(ctx, mask, this);
         
@@ -101,7 +108,12 @@ public class BlueprintExtender implement
             bt.open();
           }
           public void serviceLost() {
-            // TODO we should probably close here, not sure.
+            while (!containers.isEmpty()) {
+              for (Bundle bundle : getBundlesToDestroy()) {
+                destroyContainer(bundle);
+              }
+            }
+            bt.close();
           }
           public void serviceReplaced() {
           }
@@ -155,6 +167,20 @@ public class BlueprintExtender implement
     }
 
     /*
+     * SynchronousBundleListener
+     */
+
+    public void bundleChanged(BundleEvent event) {
+        Bundle bundle = event.getBundle();
+        if (bundle.getState() != Bundle.ACTIVE && bundle.getState() != Bundle.STARTING)
{
+            // The bundle is not in STARTING or ACTIVE state anymore
+            // so destroy the context
+            destroyContainer(bundle);
+            return;
+        }
+    }
+
+    /*
      * BundleTrackerCustomizer
      */
 
@@ -198,11 +224,20 @@ public class BlueprintExtender implement
                 // This bundle is not a blueprint bundle, so ignore it
                 return false;
             }
-            BlueprintContainerImpl blueprintContainer = new BlueprintContainerImpl(bundle.getBundleContext(),
+            ProxyManager pm = proxyManager.getService();
+            if (pm == null) {
+                // The pm isn't available.  It may be because it is being untracked
+                return false;
+            }
+            BundleContext bundleContext = bundle.getBundleContext();
+            if (bundleContext == null) {
+                // The bundle has been stopped in the mean time
+                return false;
+            }
+            BlueprintContainerImpl blueprintContainer = new BlueprintContainerImpl(bundle,
bundleContext,
                                                                 context.getBundle(), eventDispatcher,
                                                                 handlers, getExecutorService(bundle),
-                                                                executors, paths,
-                                                                proxyManager.getService());
+                                                                executors, paths, pm);
             synchronized (containers) {
                 if (containers.putIfAbsent(bundle, blueprintContainer) != null) {
                     return false;
@@ -373,7 +408,9 @@ public class BlueprintExtender implement
                     }
                 }
             }
-            bundlesToDestroy.add(ref.getBundle());
+            if (ref != null) {
+                bundlesToDestroy.add(ref.getBundle());
+            }
             LOGGER.debug("Selected bundle {} for destroy (lowest ranking service)", bundlesToDestroy);
         }
         return bundlesToDestroy;

Modified: aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/TestBlueprintContainer.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/TestBlueprintContainer.java?rev=1422911&r1=1422910&r2=1422911&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/TestBlueprintContainer.java
(original)
+++ aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/TestBlueprintContainer.java
Mon Dec 17 12:48:38 2012
@@ -44,7 +44,7 @@ public class TestBlueprintContainer exte
     }
 
     public TestBlueprintContainer(ComponentDefinitionRegistryImpl registry, ProxyManager
proxyManager) throws Exception {
-        super(new TestBundleContext(), null, null, null, null, null, null, proxyManager);
+        super(null, new TestBundleContext(), null, null, null, null, null, null, proxyManager);
         this.registry = registry;
         if (registry != null) {
             registry.registerComponentDefinition(new PassThroughMetadataImpl("blueprintContainer",
this));

Modified: aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/BeanRecipeTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/BeanRecipeTest.java?rev=1422911&r1=1422910&r2=1422911&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/BeanRecipeTest.java
(original)
+++ aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/BeanRecipeTest.java
Mon Dec 17 12:48:38 2012
@@ -120,7 +120,7 @@ public class BeanRecipeTest {
 
     @Test
     public void parameterWithGenerics() throws Exception {
-        BlueprintContainerImpl container = new BlueprintContainerImpl(null, null, null, null,
null, null, null, null);
+        BlueprintContainerImpl container = new BlueprintContainerImpl(null, null, null, null,
null, null, null, null, null);
         BeanRecipe recipe = new BeanRecipe("example", container, ExampleService.class, false);
         recipe.setArguments(Arrays.<Object>asList(new ExampleImpl()));
         recipe.setArgTypes(Arrays.<String>asList((String) null));
@@ -195,7 +195,7 @@ public class BeanRecipeTest {
 
     @Test
     public void protectedClassAccess() throws Exception {
-        BlueprintContainerImpl container = new BlueprintContainerImpl(null, null, null, null,
null, null, null, null);
+        BlueprintContainerImpl container = new BlueprintContainerImpl(null, null, null, null,
null, null, null, null, null);
         BeanRecipe recipe = new BeanRecipe("a", container, null, false);
         recipe.setFactoryComponent(new PassThroughRecipe("factory", new Factory().create()));
         recipe.setFactoryMethod("getA");



Mime
View raw message