Author: andygumbrecht Date: Thu Feb 6 16:40:52 2014 New Revision: 1565329 URL: http://svn.apache.org/r1565329 Log: Fix https://issues.apache.org/jira/browse/OPENEJB-2070
Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/util/classloader/URLClassLoaderFirst.java Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/util/classloader/URLClassLoaderFirst.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/util/classloader/URLClassLoaderFirst.java?rev=1565329&r1=1565328&r2=1565329&view=diff ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/util/classloader/URLClassLoaderFirst.java (original) +++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/util/classloader/URLClassLoaderFirst.java Thu Feb 6 16:40:52 2014 @@ -22,10 +22,18 @@ import org.apache.openejb.loader.SystemI import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.concurrent.locks.ReentrantLock; // TODO: look SM usage, find a better name public class URLClassLoaderFirst extends URLClassLoader { + + private static final ReentrantLock LOCK; + // log4j is optional, moreover it will likely not work if not skipped and loaded by a temp classloader private static final boolean SKIP_LOG4J = "true".equals(SystemInstance.get().getProperty("openejb.skip.log4j", "true")) && skipLib("org.apache.log4j.Logger"); private static final boolean SKIP_MYFACES = "true".equals(SystemInstance.get().getProperty("openejb.skip.myfaces", "true")) && skipLib("org.apache.myfaces.spi.FactoryFinderProvider"); @@ -43,6 +51,7 @@ public class URLClassLoaderFirst extends public static final Collection<String> FORCED_LOAD = new ArrayList<String>(); static { + LOCK = new ReentrantLock(); reloadConfig(); } @@ -69,7 +78,7 @@ public class URLClassLoaderFirst extends try { URLClassLoaderFirst.class.getClassLoader().loadClass(includedClass); return true; - } catch (ClassNotFoundException e) { + } catch (final ClassNotFoundException e) { return false; } } @@ -83,53 +92,61 @@ public class URLClassLoaderFirst extends @Override public Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException { - // already loaded? - Class<?> clazz = findLoadedClass(name); - if (clazz != null) { - if (resolve) { - resolveClass(clazz); - } - return clazz; - } - // JSE classes? - if (canBeLoadedFromSystem(name)) { - try { - clazz = system.loadClass(name); - if (clazz != null) { - if (resolve) { - resolveClass(clazz); + final ReentrantLock lock = LOCK; + lock.lock(); + + try { + // already loaded? + Class<?> clazz = findLoadedClass(name); + if (clazz != null) { + if (resolve) { + resolveClass(clazz); + } + return clazz; + } + + // JSE classes? + if (canBeLoadedFromSystem(name)) { + try { + clazz = system.loadClass(name); + if (clazz != null) { + if (resolve) { + resolveClass(clazz); + } + return clazz; } + } catch (final ClassNotFoundException ignored) { + // no-op + } + } + + // look for it in this classloader + final boolean ok = !(shouldSkip(name) || shouldDelegateToTheContainer(this, name)); + if (ok) { + clazz = loadInternal(name, resolve); + if (clazz != null) { return clazz; } - } catch (ClassNotFoundException ignored) { - // no-op } - } - // look for it in this classloader - boolean ok = !(shouldSkip(name) || shouldDelegateToTheContainer(this, name)); - if (ok) { - clazz = loadInternal(name, resolve); + // finally delegate + clazz = loadFromParent(name, resolve); if (clazz != null) { return clazz; } - } - - // finally delegate - clazz = loadFromParent(name, resolve); - if (clazz != null) { - return clazz; - } - if (!ok) { - clazz = loadInternal(name, resolve); - if (clazz != null) { - return clazz; + if (!ok) { + clazz = loadInternal(name, resolve); + if (clazz != null) { + return clazz; + } } - } - throw new ClassNotFoundException(name); + throw new ClassNotFoundException(name); + } finally { + lock.unlock(); + } } public static boolean shouldDelegateToTheContainer(final ClassLoader loader, final String name) { @@ -149,7 +166,7 @@ public class URLClassLoaderFirst extends } return clazz; } - } catch (ClassNotFoundException ignored) { + } catch (final ClassNotFoundException ignored) { // no-op } return null; @@ -164,7 +181,7 @@ public class URLClassLoaderFirst extends } return clazz; } - } catch (ClassNotFoundException ignored) { + } catch (final ClassNotFoundException ignored) { // no-op } return null; @@ -185,12 +202,12 @@ public class URLClassLoaderFirst extends return false; } - for (String prefix : FORCED_SKIP) { + for (final String prefix : FORCED_SKIP) { if (name.startsWith(prefix)) { return true; } } - for (String prefix : FORCED_LOAD) { + for (final String prefix : FORCED_LOAD) { if (name.startsWith(prefix)) { return false; } @@ -264,7 +281,8 @@ public class URLClassLoaderFirst extends if (myfaces.startsWith("context.")) return true; if (myfaces.startsWith("logging.")) return true; // tomahawk uses component.html package - if (myfaces.startsWith("component.visit.") || myfaces.equals("component.ComponentResourceContainer")) return true; + if (myfaces.startsWith("component.visit.") || myfaces.equals("component.ComponentResourceContainer")) + return true; if (myfaces.startsWith("application.")) return true; if (myfaces.startsWith("config.")) return true; if (myfaces.startsWith("event.")) return true; @@ -281,7 +299,7 @@ public class URLClassLoaderFirst extends if (myfaces.startsWith("renderkit.")) { final String renderkit = myfaces.substring("renderkit.".length()); if (renderkit.startsWith("html.Html")) return true; - char firstNextletter = renderkit.charAt(0); + final char firstNextletter = renderkit.charAt(0); if (Character.isUpperCase(firstNextletter)) return true; return false; }