[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.
This commit is contained in:
Juan Martin Sotuyo Dodero
2017-11-21 00:16:20 -03:00
parent 0ff05ed740
commit 6028e77e62
2 changed files with 20 additions and 23 deletions

View File

@ -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<URL> 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;
}
}

View File

@ -100,7 +100,7 @@ public final class PMDASMClassLoader extends ClassLoader {
}
public synchronized Map<String, String> getImportedClasses(String name) throws ClassNotFoundException {
if (dontBother.containsValue(name)) {
if (dontBother.containsKey(name)) {
throw new ClassNotFoundException(name);
}
try (InputStream classResource = getResourceAsStream(name.replace('.', '/') + ".class")) {