From c53462b3b6a3d55f1e869c79faa275d8e86cb30b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 1 Aug 2024 11:07:36 +0200 Subject: [PATCH] Improve RuleTst performance Reuse the classloader for auxclasspath instead of creating a new one for every single rule test case. --- .../pmd/lang/java/JavaParsingHelper.java | 40 ++++--------------- .../net/sourceforge/pmd/test/RuleTst.java | 14 +++++-- 2 files changed, 18 insertions(+), 36 deletions(-) diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java index 4908c14131..d8e82c8c73 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java @@ -6,16 +6,8 @@ package net.sourceforge.pmd.lang.java; import static net.sourceforge.pmd.lang.ast.Parser.ParserTask; -import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.InputStream; import java.io.PrintStream; -import java.io.UncheckedIOException; -import java.net.URI; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; import java.text.MessageFormat; import java.util.ArrayList; import java.util.HashMap; @@ -29,6 +21,7 @@ import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import net.sourceforge.pmd.internal.util.ClasspathClassLoader; import net.sourceforge.pmd.lang.LanguageProcessor; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.ast.SemanticErrorReporter; @@ -54,32 +47,15 @@ public class JavaParsingHelper extends BaseParsingHelper { - ClassLoader classLoader = JavaParsingHelper.class.getClassLoader(); + public static final TypeSystem TEST_TYPE_SYSTEM; - if (name.endsWith("/module-info.class")) { - String moduleName = name.substring(0, name.length() - "/module-info.class".length()); - - InputStream inputStream = null; - @SuppressWarnings("PMD.CloseResource") - // this JrtFileSystem instance can't be closed (UnsupportedOperationException), - // because it used by the current running JVM - FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); - try { - Path moduleInfoPath = fs.getPath("modules", moduleName, "module-info.class"); - if (Files.exists(moduleInfoPath)) { - inputStream = new ByteArrayInputStream(Files.readAllBytes(moduleInfoPath)); - } - } catch (IOException e) { - throw new UncheckedIOException(e); - } - if (inputStream != null) { - return inputStream; - } + static { + try { + TEST_TYPE_SYSTEM = TypeSystem.usingClassLoaderClasspath(new ClasspathClassLoader("", JavaParsingHelper.class.getClassLoader())); + } catch (IOException e) { + throw new RuntimeException(e); } - - return classLoader.getResourceAsStream(name); - }); + } /** This runs all processing stages when parsing. */ public static final JavaParsingHelper DEFAULT = new JavaParsingHelper( diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/test/RuleTst.java b/pmd-test/src/main/java/net/sourceforge/pmd/test/RuleTst.java index de4b0be4b7..c22dcb9fc2 100644 --- a/pmd-test/src/main/java/net/sourceforge/pmd/test/RuleTst.java +++ b/pmd-test/src/main/java/net/sourceforge/pmd/test/RuleTst.java @@ -31,6 +31,7 @@ import org.xml.sax.InputSource; import net.sourceforge.pmd.PMDConfiguration; import net.sourceforge.pmd.PmdAnalysis; +import net.sourceforge.pmd.internal.util.ClasspathClassLoader; import net.sourceforge.pmd.lang.LanguageVersion; import net.sourceforge.pmd.lang.document.FileId; import net.sourceforge.pmd.lang.document.TextFile; @@ -225,9 +226,10 @@ public abstract class RuleTst { return runTestFromString(test.getCode(), rule, test.getLanguageVersion()); } - private static final Path PATH_TO_JRT_FS_JAR; + private static final ClassLoader TEST_AUXCLASSPATH_CLASSLOADER; static { + final Path PATH_TO_JRT_FS_JAR; // find jrt-fs.jar to be added to auxclasspath // Similar logic like jdk.internal.jrtfs.SystemImage CodeSource codeSource = Object.class.getProtectionDomain().getCodeSource(); @@ -244,6 +246,12 @@ public abstract class RuleTst { throw new IllegalStateException(e); } } + + try { + TEST_AUXCLASSPATH_CLASSLOADER = new ClasspathClassLoader(PATH_TO_JRT_FS_JAR.toString(), PMDConfiguration.class.getClassLoader()); + } catch (IOException e) { + throw new RuntimeException(e); + } } /** @@ -254,9 +262,7 @@ public abstract class RuleTst { configuration.setIgnoreIncrementalAnalysis(true); configuration.setDefaultLanguageVersion(languageVersion); configuration.setThreads(0); // don't use separate threads - configuration.prependAuxClasspath("."); - configuration.prependAuxClasspath(PATH_TO_JRT_FS_JAR.toString()); - + configuration.setClassLoader(TEST_AUXCLASSPATH_CLASSLOADER); try (PmdAnalysis pmd = PmdAnalysis.create(configuration)) { pmd.files().addFile(TextFile.forCharSeq(code, FileId.fromPathLikeString("file"), languageVersion));