From 9e4858b8c288097379e8934c8fdcf48b5864680f Mon Sep 17 00:00:00 2001 From: rsalvador Date: Wed, 28 Nov 2012 10:08:43 -0800 Subject: [PATCH] Reuse PMDASMClassLoader instance across all compilation units analyzed. --- .../typeresolution/ClassTypeResolver.java | 2 +- .../typeresolution/PMDASMClassLoader.java | 22 ++++++++++++++++--- .../typeresolution/PMDASMClassLoaderTest.java | 6 ++--- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/pmd/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/ClassTypeResolver.java b/pmd/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/ClassTypeResolver.java index 36cc7003c3..8f7fed9daa 100644 --- a/pmd/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/ClassTypeResolver.java +++ b/pmd/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/ClassTypeResolver.java @@ -134,7 +134,7 @@ public class ClassTypeResolver extends JavaParserVisitorAdapter { } public ClassTypeResolver(ClassLoader classLoader) { - pmdClassLoader = new PMDASMClassLoader(classLoader); + pmdClassLoader = PMDASMClassLoader.getInstance(classLoader); } // FUTURE ASTCompilationUnit should not be a TypeNode. Clean this up accordingly. diff --git a/pmd/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/PMDASMClassLoader.java b/pmd/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/PMDASMClassLoader.java index d7f123c446..aea52adf7e 100644 --- a/pmd/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/PMDASMClassLoader.java +++ b/pmd/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/PMDASMClassLoader.java @@ -30,16 +30,32 @@ import org.objectweb.asm.ClassReader; * then the resource foo/Bar.class will not exist, too. */ public class PMDASMClassLoader extends ClassLoader { + + private static PMDASMClassLoader cachedPMDASMClassLoader; + private static ClassLoader cachedClassLoader; + + /** + * A new PMDASMClassLoader is created for each compilation unit, this method allows to reuse the same + * PMDASMClassLoader across all the compilation units. + */ + public static synchronized PMDASMClassLoader getInstance(ClassLoader parent) { + if (parent == cachedClassLoader) return cachedPMDASMClassLoader; + cachedClassLoader = parent; + cachedPMDASMClassLoader = new PMDASMClassLoader(parent); + return cachedPMDASMClassLoader; + } + + // - public PMDASMClassLoader(ClassLoader parent) { + private PMDASMClassLoader(ClassLoader parent) { super(parent); } /** Caches the names of the classes that we can't load or that don't exist. */ - private Set dontBother = Collections.synchronizedSet(new HashSet()); + private final Set dontBother = new HashSet(); @Override - public Class loadClass(String name) throws ClassNotFoundException { + public synchronized Class loadClass(String name) throws ClassNotFoundException { if (dontBother.contains(name)) { throw new ClassNotFoundException(name); } diff --git a/pmd/src/test/java/net/sourceforge/pmd/typeresolution/PMDASMClassLoaderTest.java b/pmd/src/test/java/net/sourceforge/pmd/typeresolution/PMDASMClassLoaderTest.java index ba1b931642..be96478e51 100644 --- a/pmd/src/test/java/net/sourceforge/pmd/typeresolution/PMDASMClassLoaderTest.java +++ b/pmd/src/test/java/net/sourceforge/pmd/typeresolution/PMDASMClassLoaderTest.java @@ -17,7 +17,7 @@ public class PMDASMClassLoaderTest { @Before public void setUp() throws Exception { - cl = new PMDASMClassLoader(getClass().getClassLoader()); + cl = PMDASMClassLoader.getInstance(getClass().getClassLoader()); } /** @@ -78,7 +78,7 @@ public class PMDASMClassLoaderTest { @Test public void testCachingOfNotFoundClasses() throws Exception { MockedClassLoader mockedClassloader = new MockedClassLoader(); - PMDASMClassLoader cl = new PMDASMClassLoader(mockedClassloader); + PMDASMClassLoader cl = PMDASMClassLoader.getInstance(mockedClassloader); String notExistingClassname = "that.clazz.doesnot.Exist"; try { cl.loadClass(notExistingClassname); @@ -116,7 +116,7 @@ public class PMDASMClassLoaderTest { @Test public void testCachingMemoryConsumption() throws Exception { MockedClassLoader mockedClassLoader = new MockedClassLoader(); - PMDASMClassLoader cl = new PMDASMClassLoader(mockedClassLoader); + PMDASMClassLoader cl = PMDASMClassLoader.getInstance(mockedClassLoader); Runtime runtime = Runtime.getRuntime(); System.gc();