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<listener>\n<br/>" +
- " <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>\n<br/>" +
- "</listener>";
-
- 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<listener>\n<br/>" +
+ " <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>\n<br/>" +
+ "</listener>";
+
+ 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)