Improve RuleTst performance

Reuse the classloader for auxclasspath
instead of creating a new one for every
single rule test case.
This commit is contained in:
Andreas Dangel 2024-08-01 11:07:36 +02:00
parent d171bcbdb3
commit c53462b3b6
No known key found for this signature in database
GPG Key ID: 93450DF2DF9A3FA3
2 changed files with 18 additions and 36 deletions

View File

@ -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<JavaParsingHelper, ASTC
* default options of JavaParsingHelper. This allows constants like
* the null type to be compared.
*/
public static final TypeSystem TEST_TYPE_SYSTEM = TypeSystem.usingClasspath(name -> {
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(

View File

@ -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));