You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by st...@apache.org on 2010/07/27 17:18:05 UTC

svn commit: r979744 - /myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/listener/phase/PhaseListenerExtension.java

Author: struberg
Date: Tue Jul 27 15:18:04 2010
New Revision: 979744

URL: http://svn.apache.org/viewvc?rev=979744&view=rev
Log:
EXTCDI-34 PhaseListenerExtension is not Multi-WebApp ClassLoader safe

Modified:
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/listener/phase/PhaseListenerExtension.java

Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/listener/phase/PhaseListenerExtension.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/listener/phase/PhaseListenerExtension.java?rev=979744&r1=979743&r2=979744&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/listener/phase/PhaseListenerExtension.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/listener/phase/PhaseListenerExtension.java Tue Jul 27 15:18:04 2010
@@ -29,14 +29,21 @@ import javax.faces.event.PhaseListener;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
+ * The PhaseListenerExtension picks up all {@link JsfPhaseListener} annotated
+ * beans for later registration as PhaseListeners.
+ * We have to maintain this separately for each ContextClassLoader since it
+ * is possible that multiple WebApps start up in parallel.
  * @author Gerhard Petracek
  */
 public class PhaseListenerExtension implements Extension
 {
-    private static List<PhaseListener> phaseListeners = new CopyOnWriteArrayList<PhaseListener>();
+    private static Map<ClassLoader, List<PhaseListener>> phaseListeners = 
+            new ConcurrentHashMap<ClassLoader,List<PhaseListener>>();
 
     public void filterJsfPhaseListeners(@Observes ProcessAnnotatedType processAnnotatedType)
     {
@@ -58,11 +65,25 @@ public class PhaseListenerExtension impl
         }
         catch (IllegalStateException e)
         {
-            //current workaround some servers
-            phaseListeners.add(newPhaseListener);
+            // current workaround some servers
+            addPhaseListener(newPhaseListener);
         }
     }
 
+    private void addPhaseListener(PhaseListener newPhaseListener)
+    {
+        ClassLoader cl = ClassUtils.getClassLoader(null);
+
+        List<PhaseListener> plList = phaseListeners.get(cl);
+
+        if (plList == null)
+        {
+            plList = new CopyOnWriteArrayList<PhaseListener>();
+            phaseListeners.put(cl, plList);
+        }
+        plList.add(newPhaseListener);
+    }
+
     private PhaseListener createPhaseListenerInstance(ProcessAnnotatedType processAnnotatedType)
     {
         return ClassUtils.tryToInstantiateClass(
@@ -72,12 +93,14 @@ public class PhaseListenerExtension impl
     //current workaround some servers
     public static List<PhaseListener> consumePhaseListeners()
     {
-        int phaseListenerListSize = phaseListeners.size();
-        if(phaseListenerListSize > 0)
+        ClassLoader cl = ClassUtils.getClassLoader(null);
+        List<PhaseListener> plList = phaseListeners.get(cl);
+
+        if(plList != null && ! plList.isEmpty())
         {
-            List<PhaseListener> result = new ArrayList<PhaseListener>(phaseListenerListSize);
-            result.addAll(phaseListeners);
-            phaseListeners.clear();
+            List<PhaseListener> result = new ArrayList<PhaseListener>(plList.size());
+            result.addAll(plList);
+            plList.clear();
             return result;
         }
         return Collections.emptyList();