You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ja...@apache.org on 2011/02/23 17:37:46 UTC
svn commit: r1073815 -
/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/MyFacesClassLoader.java
Author: jakobk
Date: Wed Feb 23 16:37:45 2011
New Revision: 1073815
URL: http://svn.apache.org/viewvc?rev=1073815&view=rev
Log:
MYFACES-3051 Use multiple ClassLoaders to find resources (not only ContextClassLoader) (improve MyFacesClassLoader)
Modified:
myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/MyFacesClassLoader.java
Modified: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/MyFacesClassLoader.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/MyFacesClassLoader.java?rev=1073815&r1=1073814&r2=1073815&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/MyFacesClassLoader.java (original)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/MyFacesClassLoader.java Wed Feb 23 16:37:45 2011
@@ -18,11 +18,16 @@
*/
package org.apache.myfaces.shared.util;
+import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
+import java.util.Collections;
import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
/**
* Custom ClassLoader that sets the current Thread's context ClassLoader as parent ClassLoader
@@ -33,16 +38,60 @@ import java.util.Enumeration;
public class MyFacesClassLoader extends ClassLoader
{
+ private static final String APPLICATION_MAP_KEY = MyFacesClassLoader.class.getName();
+
+ /**
+ * Returns the cached instance of the MyFacesClassLoader for this application or a new
+ * one if now cached instance is available yet.
+ *
+ * @param externalContext
+ * @return
+ */
+ public static final MyFacesClassLoader getCurrentInstance(ExternalContext externalContext)
+ {
+ if (externalContext == null)
+ {
+ // if no ExternalContext is available, return a new instance
+ // this may be the case in Unit tests or outside of the JSF lifecycle
+ return new MyFacesClassLoader();
+ }
+
+ Map<String, Object> applicationMap = externalContext.getApplicationMap();
+ MyFacesClassLoader classLoader = (MyFacesClassLoader) applicationMap.get(APPLICATION_MAP_KEY);
+
+ if (classLoader == null)
+ {
+ // no instance available for this application yet, create one and cache it
+ classLoader = new MyFacesClassLoader();
+ applicationMap.put(APPLICATION_MAP_KEY, classLoader);
+ }
+
+ return classLoader;
+ }
+
+ private static ClassLoader getContextClassLoaderFailsafe()
+ {
+ ClassLoader contextClassLoader = ClassLoaderUtils.getContextClassLoader();
+
+ if (contextClassLoader == null)
+ {
+ // fall back to the ClassLoader of this class if the current Thread has no ContextClassLoader
+ contextClassLoader = MyFacesClassLoader.class.getClassLoader();
+ }
+
+ return contextClassLoader;
+ }
+
private ClassLoader apiClassLoader;
private ClassLoader implClassLoader;
public MyFacesClassLoader()
{
// context ClassLoader is parent ClassLoader
- super(ClassLoaderUtils.getContextClassLoader());
+ super(getContextClassLoaderFailsafe());
apiClassLoader = FacesContext.class.getClassLoader(); // myfaces-api classloader
- implClassLoader = getClass().getClassLoader(); // myfaces-impl classloader
+ implClassLoader = getClass().getClassLoader(); // myfaces-impl (or tomahawk) classloader
}
@Override
@@ -69,22 +118,19 @@ public class MyFacesClassLoader extends
@Override
public Enumeration<URL> getResources(String s) throws IOException
{
+ // use all 3 classloaders and merge without duplicates
+ Set<URL> urls = new HashSet<URL>(); // no duplicates
+
// context classloader
- Enumeration<URL> urls = super.getResources(s);
+ urls.addAll(Collections.list(super.getResources(s)));
- if (urls == null || !urls.hasMoreElements())
- {
- // try api
- urls = apiClassLoader.getResources(s);
+ // api classlaoder
+ urls.addAll(Collections.list(apiClassLoader.getResources(s)));
- if (urls == null || !urls.hasMoreElements())
- {
- // try impl
- urls = implClassLoader.getResources(s);
- }
- }
+ // impl classlaoder
+ urls.addAll(Collections.list(implClassLoader.getResources(s)));
- return urls;
+ return Collections.enumeration(urls);
}
@Override
@@ -146,6 +192,20 @@ public class MyFacesClassLoader extends
return clazz;
}
+ @Override
+ public boolean equals(Object o)
+ {
+ if (o instanceof MyFacesClassLoader)
+ {
+ MyFacesClassLoader other = (MyFacesClassLoader) o;
+
+ // same parent --> same ContextClassLoader --> same MyFacesClassLoader
+ return (other.getParent().equals(this.getParent()));
+ }
+
+ return false;
+ }
+
private Class<?> loadClassFailsafe(String s, ClassLoader classLaoder)
{
try