geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ga...@apache.org
Subject svn commit: r1306000 - in /geronimo/server/trunk/plugins: aries/geronimo-aries/ aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/ wab/geronimo-wab/src/main/java/org/apache/geronimo/osgi/web/ wab/geronimo-web-extender/ wab/geronimo-web-exten...
Date Tue, 27 Mar 2012 20:09:18 GMT
Author: gawor
Date: Tue Mar 27 20:09:17 2012
New Revision: 1306000

URL: http://svn.apache.org/viewvc?rev=1306000&view=rev
Log:
GERONIMO-6311: Wait for web bundles to initialize fully before allowing application update
to avoid a deadlock

Added:
    geronimo/server/trunk/plugins/aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/WebApplicationTracker.java
  (with props)
    geronimo/server/trunk/plugins/wab/geronimo-wab/src/main/java/org/apache/geronimo/osgi/web/WebApplicationListener.java
  (with props)
Modified:
    geronimo/server/trunk/plugins/aries/geronimo-aries/pom.xml
    geronimo/server/trunk/plugins/aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/ApplicationGBean.java
    geronimo/server/trunk/plugins/aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/ApplicationInstaller.java
    geronimo/server/trunk/plugins/wab/geronimo-web-extender/pom.xml
    geronimo/server/trunk/plugins/wab/geronimo-web-extender/src/main/java/org/apache/geronimo/osgi/web/extender/WebContainerEventDispatcher.java

Modified: geronimo/server/trunk/plugins/aries/geronimo-aries/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/aries/geronimo-aries/pom.xml?rev=1306000&r1=1305999&r2=1306000&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/aries/geronimo-aries/pom.xml (original)
+++ geronimo/server/trunk/plugins/aries/geronimo-aries/pom.xml Tue Mar 27 20:09:17 2012
@@ -40,6 +40,11 @@
             <version>${project.version}</version>
         </dependency>
         <dependency>
+            <groupId>org.apache.geronimo.modules</groupId>
+            <artifactId>geronimo-wab</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
             <groupId>org.apache.geronimo.framework</groupId>
             <artifactId>geronimo-transformer</artifactId>
             <version>${project.version}</version>

Modified: geronimo/server/trunk/plugins/aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/ApplicationGBean.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/ApplicationGBean.java?rev=1306000&r1=1305999&r2=1306000&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/ApplicationGBean.java
(original)
+++ geronimo/server/trunk/plugins/aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/ApplicationGBean.java
Tue Mar 27 20:09:17 2012
@@ -43,6 +43,7 @@ import org.apache.geronimo.gbean.annotat
 import org.apache.geronimo.gbean.annotation.SpecialAttributeType;
 import org.apache.geronimo.kernel.Kernel;
 import org.apache.geronimo.kernel.repository.Artifact;
+import org.apache.geronimo.osgi.web.WebApplicationUtils;
 import org.apache.xbean.osgi.bundle.util.BundleUtils;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -152,8 +153,9 @@ public class ApplicationGBean implements
         if (targetBundle == null) {
             throw new IllegalArgumentException("Could not find bundle with id " + bundleId
+ " in the application");
         }
-        
+        waitForStart();
         updateHelper.updateBundle(targetBundle, file);
+        waitForStart();
     }
     
     /*
@@ -168,7 +170,7 @@ public class ApplicationGBean implements
         if (targetBundle == null) {
             throw new IllegalArgumentException("Could not find bundle with id " + bundleId
+ " in the application");
         }
-
+        waitForStart();
         return updateHelper.updateBundleClasses(targetBundle, changesFile, updateArchive);
     }
    
@@ -392,6 +394,37 @@ public class ApplicationGBean implements
         }
     }
     
+    private static long getApplicationStartTimeout() {
+        String property = System.getProperty("org.apache.geronimo.aries.applicationStartTimeout",
String.valueOf(5 * 60 * 1000));
+        return Long.parseLong(property);
+    }
+    
+    private void waitForStart() {
+        waitForStart(getApplicationStartTimeout());
+    }
+    
+    private void waitForStart(long timeout) {
+        Set<Bundle> webBundles = new HashSet<Bundle>();
+        for (Bundle b : applicationBundles) {
+            if (b.getState() == Bundle.ACTIVE && WebApplicationUtils.isWebApplicationBundle(b))
{
+                webBundles.add(b);               
+            }
+        }
+        if (!webBundles.isEmpty()) {
+            LOG.debug("Waiting {}ms for asynchronous processing for {} bundles to finish",
timeout, webBundles);
+            try {
+                boolean completed = installer.getWebApplicationTracker().waitForBundles(webBundles,
timeout);
+                if (completed) {
+                    LOG.debug("Asynchronous processing completed.");                    
+                } else {
+                    LOG.debug("Time out while waiting for asynchronous processing to finish.");
+                }
+            } catch (InterruptedException e) {
+                // ignore
+            }
+        }   
+    }
+    
     public void doStop() {
         LOG.debug("Stopping {} application.", getApplicationName());
         

Modified: geronimo/server/trunk/plugins/aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/ApplicationInstaller.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/ApplicationInstaller.java?rev=1306000&r1=1305999&r2=1306000&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/ApplicationInstaller.java
(original)
+++ geronimo/server/trunk/plugins/aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/ApplicationInstaller.java
Tue Mar 27 20:09:17 2012
@@ -49,7 +49,6 @@ import org.apache.geronimo.kernel.util.B
 import org.apache.geronimo.kernel.util.FileUtils;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
-import org.osgi.framework.Version;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -66,6 +65,7 @@ public class ApplicationInstaller implem
     private AbstractName abstractName;
     private ServiceRegistration registration;
     private ConfigurationManager configurationManager;
+    private WebApplicationTracker webApplicationTracker;
     private Collection<? extends Repository> repositories;
     private Collection<ConfigurationStore> configurationStores;
     private Environment defaultEnvironment;
@@ -84,16 +84,19 @@ public class ApplicationInstaller implem
         this.configurationStores = configurationStores;
         this.configurationManager = ConfigurationUtil.getConfigurationManager(kernel);
         this.defaultEnvironment = defaultEnvironment;
+        this.webApplicationTracker = new WebApplicationTracker(bundleContext);
     }
 
     public void doStart() throws Exception {
         registration = bundleContext.registerService(ApplicationInstaller.class.getName(),
this, null);
+        webApplicationTracker.start();
     }
 
     public void doStop() {
         if (registration != null) {
             registration.unregister();
         }
+        webApplicationTracker.stop();
     }
 
     public void doFail() {
@@ -103,6 +106,10 @@ public class ApplicationInstaller implem
     protected ConfigurationManager getConfigurationManager() {
         return configurationManager;
     }
+    
+    protected WebApplicationTracker getWebApplicationTracker() {
+        return webApplicationTracker;
+    }
 
     public DeploymentContext startInstall(AriesApplication app, ConfigurationStore targetConfigurationStore)
         throws ConfigurationAlreadyExistsException, IOException, DeploymentException {

Added: geronimo/server/trunk/plugins/aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/WebApplicationTracker.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/WebApplicationTracker.java?rev=1306000&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/WebApplicationTracker.java
(added)
+++ geronimo/server/trunk/plugins/aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/WebApplicationTracker.java
Tue Mar 27 20:09:17 2012
@@ -0,0 +1,93 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.geronimo.aries;
+
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.geronimo.osgi.web.WebApplicationListener;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * @version $Rev:385232 $ $Date$
+ */
+public class WebApplicationTracker implements WebApplicationListener {
+
+    private final BundleContext bundleContext;
+    private ServiceRegistration registration;
+    // list of bundles that are deployed successfully or failed to deploy
+    private Set<Bundle> completed;
+    
+    public WebApplicationTracker(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+        this.completed = Collections.synchronizedSet(new HashSet<Bundle>());
+    }
+    
+    public void start() {
+        registration = bundleContext.registerService(WebApplicationListener.class.getName(),
this, null);
+    }
+    
+    public void stop() {
+        if (registration != null) {
+            registration.unregister();
+        }
+    }
+
+    public synchronized boolean waitForBundles(Set<Bundle> bundles, long timeout) throws
InterruptedException {
+        while (!completed.containsAll(bundles)) {
+            if (timeout <= 0) {
+                return false;
+            }
+            long startTime = System.currentTimeMillis();
+            wait(timeout);
+            long endTime = System.currentTimeMillis();
+            timeout -= (endTime - startTime);
+        }
+        return true;
+    }
+    
+    @Override
+    public synchronized void deployed(Bundle bundle, String contextPath, Dictionary<String,
Object> arg2) {
+        completed.add(bundle);
+        notifyAll();
+    }
+
+    @Override
+    public synchronized void deploying(Bundle bundle, String contextPath, Dictionary<String,
Object> arg2) {
+        completed.remove(bundle);
+    }
+
+    @Override
+    public synchronized void failed(Bundle bundle, String contextPath, Dictionary<String,
Object> arg2) {
+        completed.add(bundle);
+        notifyAll();
+    }
+
+    @Override
+    public synchronized void undeployed(Bundle bundle, String contextPath, Dictionary<String,
Object> arg2) {
+    }
+
+    @Override
+    public synchronized void undeploying(Bundle bundle, String contextPath, Dictionary<String,
Object> arg2) {
+        completed.remove(bundle);
+    }
+   
+}

Propchange: geronimo/server/trunk/plugins/aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/WebApplicationTracker.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/WebApplicationTracker.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/aries/geronimo-aries/src/main/java/org/apache/geronimo/aries/WebApplicationTracker.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/plugins/wab/geronimo-wab/src/main/java/org/apache/geronimo/osgi/web/WebApplicationListener.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/wab/geronimo-wab/src/main/java/org/apache/geronimo/osgi/web/WebApplicationListener.java?rev=1306000&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/wab/geronimo-wab/src/main/java/org/apache/geronimo/osgi/web/WebApplicationListener.java
(added)
+++ geronimo/server/trunk/plugins/wab/geronimo-wab/src/main/java/org/apache/geronimo/osgi/web/WebApplicationListener.java
Tue Mar 27 20:09:17 2012
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.geronimo.osgi.web;
+
+import java.util.Dictionary;
+
+import org.osgi.framework.Bundle;
+
+public interface WebApplicationListener {
+
+    void deploying(Bundle bundle, String contextPath, Dictionary<String, Object> properties);
+
+    void deployed(Bundle bundle, String contextPath, Dictionary<String, Object> properties);
+
+    void undeploying(Bundle bundle, String contextPath, Dictionary<String, Object>
properties);
+
+    void undeployed(Bundle bundle, String contextPath, Dictionary<String, Object> properties);
+
+    void failed(Bundle bundle, String contextPath, Dictionary<String, Object> properties);
+    
+}

Propchange: geronimo/server/trunk/plugins/wab/geronimo-wab/src/main/java/org/apache/geronimo/osgi/web/WebApplicationListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/wab/geronimo-wab/src/main/java/org/apache/geronimo/osgi/web/WebApplicationListener.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/wab/geronimo-wab/src/main/java/org/apache/geronimo/osgi/web/WebApplicationListener.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: geronimo/server/trunk/plugins/wab/geronimo-web-extender/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/wab/geronimo-web-extender/pom.xml?rev=1306000&r1=1305999&r2=1306000&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/wab/geronimo-web-extender/pom.xml (original)
+++ geronimo/server/trunk/plugins/wab/geronimo-web-extender/pom.xml Tue Mar 27 20:09:17 2012
@@ -47,6 +47,12 @@
 
         <dependency>
             <groupId>org.apache.geronimo.modules</groupId>
+            <artifactId>geronimo-wab</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.geronimo.modules</groupId>
             <artifactId>geronimo-web-2.5-builder</artifactId>
             <version>${project.version}</version>
         </dependency>

Modified: geronimo/server/trunk/plugins/wab/geronimo-web-extender/src/main/java/org/apache/geronimo/osgi/web/extender/WebContainerEventDispatcher.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/wab/geronimo-web-extender/src/main/java/org/apache/geronimo/osgi/web/extender/WebContainerEventDispatcher.java?rev=1306000&r1=1305999&r2=1306000&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/wab/geronimo-web-extender/src/main/java/org/apache/geronimo/osgi/web/extender/WebContainerEventDispatcher.java
(original)
+++ geronimo/server/trunk/plugins/wab/geronimo-web-extender/src/main/java/org/apache/geronimo/osgi/web/extender/WebContainerEventDispatcher.java
Tue Mar 27 20:09:17 2012
@@ -21,15 +21,20 @@ package org.apache.geronimo.osgi.web.ext
 import java.util.Collection;
 import java.util.Dictionary;
 import java.util.Hashtable;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
 
+import org.apache.geronimo.osgi.web.WebApplicationListener;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
 import org.osgi.framework.Version;
 import org.osgi.service.event.Event;
 import org.osgi.service.event.EventAdmin;
 import org.osgi.service.event.EventConstants;
 import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -47,8 +52,11 @@ public class WebContainerEventDispatcher
     private ServiceTracker tracker;
     // the extender bundle we're working on behalf of
     private Bundle extenderBundle;
+    // service tracker for WebApplicationListener
+    private ServiceTracker listenerTracker;
+    private final Set<WebApplicationListener> listeners = new CopyOnWriteArraySet<WebApplicationListener>();
 
-    public WebContainerEventDispatcher(BundleContext bundleContext) {
+    public WebContainerEventDispatcher(final BundleContext bundleContext) {
         this.extenderBundle = bundleContext.getBundle();
 
         if (isEventAdminPresent()) {
@@ -56,6 +64,23 @@ public class WebContainerEventDispatcher
             tracker = new ServiceTracker(bundleContext, EventAdmin.class.getName(), null);
             tracker.open();
         }
+        
+        listenerTracker = new ServiceTracker(bundleContext, WebApplicationListener.class.getName(),
new ServiceTrackerCustomizer() {
+            public Object addingService(ServiceReference reference) {
+                WebApplicationListener listener = (WebApplicationListener) bundleContext.getService(reference);
+                listeners.add(listener);
+                return listener;
+            }
+
+            public void modifiedService(ServiceReference reference, Object service) {
+            }
+
+            public void removedService(ServiceReference reference, Object service) {
+                listeners.remove(service);
+                bundleContext.ungetService(reference);
+            }
+        });
+        listenerTracker.open();
     }
     
     private boolean isEventAdminPresent() {
@@ -77,7 +102,16 @@ public class WebContainerEventDispatcher
      *               The context path information from the bundle.
      */
     public void deploying(Bundle bundle, String contextPath) {
-        dispatch(WebContainerConstants.TOPIC_DEPLOYING, bundle, contextPath);
+        Dictionary<String, Object> properties = createDefaultProperties(bundle, contextPath);
+        for (WebApplicationListener listener : listeners) {
+            try {
+                listener.deploying(bundle, contextPath, properties);
+            } catch (Exception e) {
+                LOGGER.warn("Error notifying listener: " + listener, e);
+                break;
+            }
+        }
+        dispatch(WebContainerConstants.TOPIC_DEPLOYING, properties);
     }
 
     /**
@@ -88,7 +122,16 @@ public class WebContainerEventDispatcher
      *               The context path information from the bundle.
      */
     public void deployed(Bundle bundle, String contextPath) {
-        dispatch(WebContainerConstants.TOPIC_DEPLOYED, bundle, contextPath);
+        Dictionary<String, Object> properties = createDefaultProperties(bundle, contextPath);
+        for (WebApplicationListener listener : listeners) {
+            try {
+                listener.deployed(bundle, contextPath, properties);
+            } catch (Exception e) {
+                LOGGER.warn("Error notifying listener: " + listener, e);
+                break;
+            }
+        }
+        dispatch(WebContainerConstants.TOPIC_DEPLOYED, properties);
     }
 
     /**
@@ -99,7 +142,16 @@ public class WebContainerEventDispatcher
      *               The context path information from the bundle.
      */
     public void undeploying(Bundle bundle, String contextPath) {
-        dispatch(WebContainerConstants.TOPIC_UNDEPLOYING, bundle, contextPath);
+        Dictionary<String, Object> properties = createDefaultProperties(bundle, contextPath);
+        for (WebApplicationListener listener : listeners) {
+            try {
+                listener.undeploying(bundle, contextPath, properties);
+            } catch (Exception e) {
+                LOGGER.warn("Error notifying listener: " + listener, e);
+                break;
+            }
+        }
+        dispatch(WebContainerConstants.TOPIC_UNDEPLOYING, properties);
     }
 
     /**
@@ -110,7 +162,16 @@ public class WebContainerEventDispatcher
      *               The context path information from the bundle.
      */
     public void undeployed(Bundle bundle, String contextPath) {
-        dispatch(WebContainerConstants.TOPIC_UNDEPLOYED, bundle, contextPath);
+        Dictionary<String, Object> properties = createDefaultProperties(bundle, contextPath);
+        for (WebApplicationListener listener : listeners) {
+            try {
+                listener.undeployed(bundle, contextPath, properties);
+            } catch (Exception e) {
+                LOGGER.warn("Error notifying listener: " + listener, e);
+                break;
+            }
+        }
+        dispatch(WebContainerConstants.TOPIC_UNDEPLOYED, properties);
     }
 
     /**
@@ -121,15 +182,19 @@ public class WebContainerEventDispatcher
      *               The context path information from the bundle.
      */
     public void failed(Bundle bundle, String contextPath, Throwable cause) {
-        EventAdmin eventAdmin = getEventAdmin();
-        if (eventAdmin == null) {
-            return;
-        }
-        Dictionary<String, Object> props = createDefaultProperties(bundle, contextPath);
+        Dictionary<String, Object> properties = createDefaultProperties(bundle, contextPath);
         if (cause != null) {
-            props.put(EventConstants.EXCEPTION, cause);
+            properties.put(EventConstants.EXCEPTION, cause);
+        }
+        for (WebApplicationListener listener : listeners) {
+            try {
+                listener.failed(bundle, contextPath, properties);
+            } catch (Exception e) {
+                LOGGER.warn("Error notifying listener: " + listener, e);
+                break;
+            }
         }
-        eventAdmin.postEvent(new Event(WebContainerConstants.TOPIC_FAILED, props));
+        dispatch(WebContainerConstants.TOPIC_FAILED, properties);
     }
     
     /**
@@ -140,16 +205,20 @@ public class WebContainerEventDispatcher
      *               The context path information from the bundle.
      */
     public void collision(Bundle bundle, String contextPath, Collection<Long> bundleId)
{
-        EventAdmin eventAdmin = getEventAdmin();
-        if (eventAdmin == null) {
-            return;
+        Dictionary<String, Object> properties = createDefaultProperties(bundle, contextPath);
+        properties.put(WebContainerConstants.COLLISION, contextPath);
+        properties.put(WebContainerConstants.COLLISION_BUNDLES, bundleId);
+        for (WebApplicationListener listener : listeners) {
+            try {
+                listener.failed(bundle, contextPath, properties);
+            } catch (Exception e) {
+                LOGGER.warn("Error notifying listener: " + listener, e);
+                break;
+            }
         }
-        Dictionary<String, Object> props = createDefaultProperties(bundle, contextPath);
-        props.put(WebContainerConstants.COLLISION, contextPath);
-        props.put(WebContainerConstants.COLLISION_BUNDLES, bundleId);
-        eventAdmin.postEvent(new Event(WebContainerConstants.TOPIC_FAILED, props));
+        dispatch(WebContainerConstants.TOPIC_FAILED, properties);
     }
-    
+        
     /**
      * Dispatch an event to the appropriate listeners.
      *
@@ -158,12 +227,11 @@ public class WebContainerEventDispatcher
      * @param contextPath
      *               The contextPath information from the bundle.
      */
-    private void dispatch(String topic, Bundle bundle, String contextPath) {
+    private void dispatch(String topic, Dictionary<String, Object> props) {
         EventAdmin eventAdmin = getEventAdmin();
         if (eventAdmin == null) {
             return;
         }
-        Dictionary<String, Object> props = createDefaultProperties(bundle, contextPath);
         eventAdmin.postEvent(new Event(topic, props));
     }
 
@@ -194,6 +262,7 @@ public class WebContainerEventDispatcher
         if (tracker != null) {
             tracker.close();
         }
+        listenerTracker.close();
     }
 
     private Version getBundleVersion(Bundle bundle) {



Mime
View raw message