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 20:44:17 UTC

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

Author: werpu
Date: Wed Dec 16 19:44:16 2009
New Revision: 891400

URL: http://svn.apache.org/viewvc?rev=891400&view=rev
Log:
https://issues.apache.org/jira/browse/EXTSCRIPT-30
fixing a concurrent modification exception at bean refresh stage for myfaces 2.0

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=891400&r1=891399&r2=891400&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 19:44:16 2009
@@ -286,7 +286,10 @@
 
             getLog().info("[EXT-SCRIPTING] Tainting all beans to avoid classcast exceptions");
             if (managedBeanTainted) {
-                for (Map.Entry<String, ManagedBean> entry : mbeans.entrySet()) {
+
+                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
@@ -306,6 +309,14 @@
 
     }
 
+    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());
+        }
+        return workCopy;
+    }
+
     private void updateBeanRefreshTime() {
         long sessionRefreshTime = System.currentTimeMillis();
         FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(ScriptingConst.SESS_BEAN_REFRESH_TIMER, sessionRefreshTime);
@@ -327,8 +338,11 @@
     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
 
-        for (Map.Entry<String, ManagedBean> entry : mbeans.entrySet()) {
+        Map<String, ManagedBean> workCopy = makeSnapshot(mbeans);
+
+        for (Map.Entry<String, ManagedBean> entry : workCopy.entrySet()) {
 
             Class managedBeanClass = entry.getValue().getManagedBeanClass();
             if (WeavingContext.isDynamic(managedBeanClass)) {
@@ -401,11 +415,11 @@
         List<String> retVal = new LinkedList<String>();
 
         for (String scriptPath : scriptPaths) {
-            List<File> tmpList = FileUtils.fetchSourceFiles(new File(scriptPath), "*"+getFileEnding());
+            List<File> tmpList = FileUtils.fetchSourceFiles(new File(scriptPath), "*" + getFileEnding());
             int lenRoot = scriptPath.length();
             //ok O(n2) but we are lazy for now if this imposes a problem we can flatten the inner loop out
             for (File sourceFile : tmpList) {
-                String relativeFile = sourceFile.getAbsolutePath().substring(lenRoot+1);
+                String relativeFile = sourceFile.getAbsolutePath().substring(lenRoot + 1);
                 String className = ClassUtils.relativeFileToClassName(relativeFile);
                 retVal.add(className);
             }