You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by we...@apache.org on 2009/12/16 22:14:45 UTC

svn commit: r891427 - /myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/BaseWeaver.java

Author: werpu
Date: Wed Dec 16 21:14:41 2009
New Revision: 891427

URL: http://svn.apache.org/viewvc?rev=891427&view=rev
Log:
added mutexes on the correct parts of the system so that the iteration over the beans does not happen at the same time as the alteration

Modified:
    myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/BaseWeaver.java

Modified: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/BaseWeaver.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/BaseWeaver.java?rev=891427&r1=891426&r2=891427&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/BaseWeaver.java (original)
+++ myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/BaseWeaver.java Wed Dec 16 21:14:41 2009
@@ -262,18 +262,22 @@
             return;//no npe allowed
         }
         Set<String> tainted = new HashSet<String>();
-        for (Map.Entry<String, ReloadingMetadata> it : WeavingContext.getFileChangedDaemon().getClassMap().entrySet()) {
-            if (it.getValue().getScriptingEngine() == getScriptingEngine() && it.getValue().isTainted()) {
-                tainted.add(it.getKey());
+        synchronized (this) {
+            for (Map.Entry<String, ReloadingMetadata> it : WeavingContext.getFileChangedDaemon().getClassMap().entrySet()) {
+                if (it.getValue().getScriptingEngine() == getScriptingEngine() && it.getValue().isTainted()) {
+                    tainted.add(it.getKey());
+                }
             }
         }
         if (tainted.size() > 0) {
             boolean managedBeanTainted = false;
             //We now have to check if the tainted classes belong to the managed beans
             Set<String> managedBeanClasses = new HashSet<String>();
-            Map<String, ManagedBean> mbeans = RuntimeConfig.getCurrentInstance(FacesContext.getCurrentInstance().getExternalContext()).getManagedBeans();
-            for (Map.Entry<String, ManagedBean> entry : mbeans.entrySet()) {
-                managedBeanClasses.add(entry.getValue().getManagedBeanClassName());
+            synchronized (this) {
+                Map<String, ManagedBean> mbeans = RuntimeConfig.getCurrentInstance(FacesContext.getCurrentInstance().getExternalContext()).getManagedBeans();
+                for (Map.Entry<String, ManagedBean> entry : mbeans.entrySet()) {
+                    managedBeanClasses.add(entry.getValue().getManagedBeanClassName());
+                }
             }
             for (String taintedClass : tainted) {
                 if (managedBeanClasses.contains(taintedClass)) {
@@ -287,20 +291,22 @@
             getLog().info("[EXT-SCRIPTING] Tainting all beans to avoid classcast exceptions");
             if (managedBeanTainted) {
 
-                Map<String, ManagedBean> workCopy = makeSnapshot(mbeans);
+                synchronized (this) {
+                    Map<String, ManagedBean> workCopy = makeSnapshot(mbeans);
 
-                for (Map.Entry<String, ManagedBean> entry : workCopy.entrySet()) {
-                    Class managedBeanClass = entry.getValue().getManagedBeanClass();
-                    if (WeavingContext.isDynamic(managedBeanClass)) {
-                        //managed bean class found we drop the class from our session
-                        removeBeanReferences(entry.getValue());
-                    }
-                    //one bean tainted we have to taint all dynamic beans otherwise we will get classcast
-                    //exceptions
-                    getLog().info("[EXT-SCRIPTING] Tainting ");
-                    ReloadingMetadata metaData = WeavingContext.getFileChangedDaemon().getClassMap().get(managedBeanClass.getName());
-                    if (metaData != null) {
-                        metaData.setTainted(true);
+                    for (Map.Entry<String, ManagedBean> entry : workCopy.entrySet()) {
+                        Class managedBeanClass = entry.getValue().getManagedBeanClass();
+                        if (WeavingContext.isDynamic(managedBeanClass)) {
+                            //managed bean class found we drop the class from our session
+                            removeBeanReferences(entry.getValue());
+                        }
+                        //one bean tainted we have to taint all dynamic beans otherwise we will get classcast
+                        //exceptions
+                        getLog().info("[EXT-SCRIPTING] Tainting ");
+                        ReloadingMetadata metaData = WeavingContext.getFileChangedDaemon().getClassMap().get(managedBeanClass.getName());
+                        if (metaData != null) {
+                            metaData.setTainted(true);
+                        }
                     }
                 }
 
@@ -318,7 +324,7 @@
      * @param mbeans
      * @return
      */
-    private synchronized Map<String, ManagedBean> makeSnapshot(Map<String, ManagedBean> mbeans) {
+    private Map<String, ManagedBean> makeSnapshot(Map<String, ManagedBean> mbeans) {
         Map<String, ManagedBean> workCopy = new HashMap<String, ManagedBean>(mbeans.size());
         for (Map.Entry<String, ManagedBean> entry : mbeans.entrySet()) {
             workCopy.put(entry.getKey(), entry.getValue());
@@ -346,33 +352,39 @@
      */
     private void refreshPersonalScopedBeans() {
 
-        Map<String, ManagedBean> mbeans = RuntimeConfig.getCurrentInstance(FacesContext.getCurrentInstance().getExternalContext()).getManagedBeans();
-        //the map is immutable but in between scanning might change it so we make a full copy of the map
-
-        Map<String, ManagedBean> workCopy = makeSnapshot(mbeans);
-
-        for (Map.Entry<String, ManagedBean> entry : workCopy.entrySet()) {
-
-            Class managedBeanClass = entry.getValue().getManagedBeanClass();
-            if (WeavingContext.isDynamic(managedBeanClass)) {
-                String scope = entry.getValue().getManagedBeanScope();
+        synchronized (this) {
+            Map<String, ManagedBean> mbeans = RuntimeConfig.getCurrentInstance(FacesContext.getCurrentInstance().getExternalContext()).getManagedBeans();
+            //the map is immutable but in between scanning might change it so we make a full copy of the map
 
-                if (scope != null && !scope.equalsIgnoreCase(SCOPE_APPLICATION)) {
-                    if (scope.equalsIgnoreCase(SCOPE_REQUEST)) {
-                        //request, nothing has to be done here
-                        return;
-                    }
-                    if (scope.equalsIgnoreCase(SCOPE_SESSION)) {
-                        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(entry.getValue().getManagedBeanName());
-                    } else {
-                        removeCustomScopedBean(entry.getValue());
+            //We can synchronized the refresh, but if someone alters
+            //the bean map from outside we still get race conditions
+            //But for most cases this mutex should be enough 
+            Map<String, ManagedBean> workCopy = makeSnapshot(mbeans);
+
+            for (Map.Entry<String, ManagedBean> entry : workCopy.entrySet()) {
+
+                Class managedBeanClass = entry.getValue().getManagedBeanClass();
+                if (WeavingContext.isDynamic(managedBeanClass)) {
+                    String scope = entry.getValue().getManagedBeanScope();
+
+                    if (scope != null && !scope.equalsIgnoreCase(SCOPE_APPLICATION)) {
+                        if (scope.equalsIgnoreCase(SCOPE_REQUEST)) {
+                            //request, nothing has to be done here
+                            return;
+                        }
+                        if (scope.equalsIgnoreCase(SCOPE_SESSION)) {
+                            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(entry.getValue().getManagedBeanName());
+                        } else {
+                            removeCustomScopedBean(entry.getValue());
+                        }
                     }
+
                 }
 
+                updateBeanRefreshTime();
             }
         }
 
-        updateBeanRefreshTime();
     }
 
     /**