You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2008/04/03 23:29:33 UTC

svn commit: r644517 - /myfaces/core/trunk/api/src/main/java/javax/faces/FactoryFinder.java

Author: lu4242
Date: Thu Apr  3 14:29:33 2008
New Revision: 644517

URL: http://svn.apache.org/viewvc?rev=644517&view=rev
Log:
fix MYFACES-1796 FactoryFinder.releaseFactories() does not release application class loader.

Modified:
    myfaces/core/trunk/api/src/main/java/javax/faces/FactoryFinder.java

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/FactoryFinder.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/FactoryFinder.java?rev=644517&r1=644516&r2=644517&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/FactoryFinder.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/FactoryFinder.java Thu Apr  3 14:29:33 2008
@@ -77,47 +77,54 @@
             throw new NullPointerException("factoryName may not be null");
 
         ClassLoader classLoader = getClassLoader();
-        Map factoryClassNames = (Map) _registeredFactoryNames.get(classLoader);
-
-        if (factoryClassNames == null)
-        {
-            String message = "No Factories configured for this Application. This happens if the faces-initialization "+
-            "does not work at all - make sure that you properly include all configuration settings necessary for a basic faces application " +
-            "and that all the necessary libs are included. <br/>\n "+
-            "Make sure that the JSF-API (myfaces-api-xxx.jar) is not included twice on the classpath - if not, the factories might be configured in the wrong class instance. <br/>\n"+
-            "If you use Tomcat, it might also pay off to clear your /[tomcat-installation]/work/ directory - Tomcat sometimes stumbles over its own tld-cache stored there, and doesn't load the StartupServletContextListener. <br/>\n"+
-            "Also check the logging output of your web application and your container for any exceptions! \n<br/>" +
-            "If you did that and find nothing, the mistake might be due to the fact that you use one of the very few web-containers which "+
-            "do not support registering context-listeners via TLD files and " +
-            "a context listener is not setup in your web.xml. <br/>\n" +
-            "Add the following lines to your web.xml file to work around this issue : <br/>\n&lt;listener&gt;\n<br/>" +
-            "  &lt;listener-class&gt;org.apache.myfaces.webapp.StartupServletContextListener&lt;/listener-class&gt;\n<br/>" +
-            "&lt;/listener&gt;";
-
-            throw new IllegalStateException(message);
-        }
-
-        if (! factoryClassNames.containsKey(factoryName)) {
-            throw new IllegalArgumentException("no factory " + factoryName + " configured for this application.");
-        }
-
-        Map factoryMap = (Map) _factories.get(classLoader);
-
-        if (factoryMap == null) {
-            factoryMap = new HashMap();
-            _factories.put(classLoader, factoryMap);
-        }
-        Object factory = factoryMap.get(factoryName);
-
-        if (factory == null) {
-            List classNames = (List) factoryClassNames.get(factoryName);
-            factory = newFactoryInstance((Class)ABSTRACT_FACTORY_CLASSES.get(factoryName), classNames.iterator(), classLoader);
-            factoryMap.put(factoryName, factory);
-            return factory;
-        }
-        else
-        {
-            return factory;
+        
+        //This code must be synchronized because this could cause a problem when
+        //using update feature each time of myfaces (org.apache.myfaces.CONFIG_REFRESH_PERIOD)
+        //In this moment, a concurrency problem could happen
+        synchronized(_registeredFactoryNames)
+        {        
+            Map factoryClassNames = (Map) _registeredFactoryNames.get(classLoader);
+    
+            if (factoryClassNames == null)
+            {
+                String message = "No Factories configured for this Application. This happens if the faces-initialization "+
+                "does not work at all - make sure that you properly include all configuration settings necessary for a basic faces application " +
+                "and that all the necessary libs are included. <br/>\n "+
+                "Make sure that the JSF-API (myfaces-api-xxx.jar) is not included twice on the classpath - if not, the factories might be configured in the wrong class instance. <br/>\n"+
+                "If you use Tomcat, it might also pay off to clear your /[tomcat-installation]/work/ directory - Tomcat sometimes stumbles over its own tld-cache stored there, and doesn't load the StartupServletContextListener. <br/>\n"+
+                "Also check the logging output of your web application and your container for any exceptions! \n<br/>" +
+                "If you did that and find nothing, the mistake might be due to the fact that you use one of the very few web-containers which "+
+                "do not support registering context-listeners via TLD files and " +
+                "a context listener is not setup in your web.xml. <br/>\n" +
+                "Add the following lines to your web.xml file to work around this issue : <br/>\n&lt;listener&gt;\n<br/>" +
+                "  &lt;listener-class&gt;org.apache.myfaces.webapp.StartupServletContextListener&lt;/listener-class&gt;\n<br/>" +
+                "&lt;/listener&gt;";
+    
+                throw new IllegalStateException(message);
+            }
+    
+            if (! factoryClassNames.containsKey(factoryName)) {
+                throw new IllegalArgumentException("no factory " + factoryName + " configured for this application.");
+            }
+    
+            Map factoryMap = (Map) _factories.get(classLoader);
+    
+            if (factoryMap == null) {
+                factoryMap = new HashMap();
+                _factories.put(classLoader, factoryMap);
+            }
+            Object factory = factoryMap.get(factoryName);
+    
+            if (factory == null) {
+                List classNames = (List) factoryClassNames.get(factoryName);
+                factory = newFactoryInstance((Class)ABSTRACT_FACTORY_CLASSES.get(factoryName), classNames.iterator(), classLoader);
+                factoryMap.put(factoryName, factory);
+                return factory;
+            }
+            else
+            {
+                return factory;
+            }
         }
     }
 
@@ -225,7 +232,18 @@
             throws FacesException
     {
         ClassLoader classLoader = getClassLoader();
-        _factories.remove(classLoader);
+        
+        //This code must be synchronized
+        synchronized(_registeredFactoryNames)
+        {
+            _factories.remove(classLoader);            
+            
+            // _registeredFactoryNames has as value type Map<String,List> and this must
+            //be cleaned before release (for gc).
+            Map factoryClassNames = _registeredFactoryNames.get(classLoader);
+            if (factoryClassNames != null) factoryClassNames.clear();
+            _registeredFactoryNames.remove(classLoader);
+        }
     }
 
     private static void checkFactoryName(String factoryName)