From 6028e77e62a1ef338999cce0b9ae5bfda3f782d4 Mon Sep 17 00:00:00 2001 From: Juan Martin Sotuyo Dodero Date: Tue, 21 Nov 2017 00:16:20 -0300 Subject: [PATCH] [core] Improve classloaders - Avoid a race condition that could produce multiple threads loading the same class at the same time. - Fixed a broken check on PMDASMClassLoader that would always return false. --- .../pmd/util/ClasspathClassLoader.java | 41 +++++++++---------- .../typeresolution/PMDASMClassLoader.java | 2 +- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/ClasspathClassLoader.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/ClasspathClassLoader.java index 29dfeccfa2..d32c13160b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/ClasspathClassLoader.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/ClasspathClassLoader.java @@ -17,7 +17,6 @@ import java.util.StringTokenizer; import java.util.logging.Level; import java.util.logging.Logger; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; /** @@ -30,7 +29,7 @@ import org.apache.commons.lang3.StringUtils; public class ClasspathClassLoader extends URLClassLoader { private static final Logger LOG = Logger.getLogger(ClasspathClassLoader.class.getName()); - + static { registerAsParallelCapable(); } @@ -64,9 +63,7 @@ public class ClasspathClassLoader extends URLClassLoader { } private static void addFileURLs(List urls, URL fileURL) throws IOException { - BufferedReader in = null; - try { - in = new BufferedReader(new InputStreamReader(fileURL.openStream())); + try (BufferedReader in = new BufferedReader(new InputStreamReader(fileURL.openStream()))) { String line; while ((line = in.readLine()) != null) { LOG.log(Level.FINE, "Read classpath entry line: <{0}>", line); @@ -76,8 +73,6 @@ public class ClasspathClassLoader extends URLClassLoader { urls.add(createURLFromPath(line)); } } - } finally { - IOUtils.closeQuietly(in); } } @@ -99,22 +94,24 @@ public class ClasspathClassLoader extends URLClassLoader { @Override protected Class loadClass(final String name, final boolean resolve) throws ClassNotFoundException { - // First, check if the class has already been loaded - Class c = findLoadedClass(name); - if (c == null) { - try { - // checking local - c = findClass(name); - } catch (final ClassNotFoundException | SecurityException e) { - // checking parent - // This call to loadClass may eventually call findClass again, in case the parent doesn't find anything. - c = super.loadClass(name, resolve); + synchronized (getClassLoadingLock(name)) { + // First, check if the class has already been loaded + Class c = findLoadedClass(name); + if (c == null) { + try { + // checking local + c = findClass(name); + } catch (final ClassNotFoundException | SecurityException e) { + // checking parent + // This call to loadClass may eventually call findClass again, in case the parent doesn't find anything. + c = super.loadClass(name, resolve); + } } + + if (resolve) { + resolveClass(c); + } + return c; } - - if (resolve) { - resolveClass(c); - } - return c; } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/PMDASMClassLoader.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/PMDASMClassLoader.java index ad130b8be5..9ecb0d9d3e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/PMDASMClassLoader.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/PMDASMClassLoader.java @@ -100,7 +100,7 @@ public final class PMDASMClassLoader extends ClassLoader { } public synchronized Map getImportedClasses(String name) throws ClassNotFoundException { - if (dontBother.containsValue(name)) { + if (dontBother.containsKey(name)) { throw new ClassNotFoundException(name); } try (InputStream classResource = getResourceAsStream(name.replace('.', '/') + ".class")) {