I’m setting up PMD using the built in Gradle plugin, having previously had it running in our Maven build before we migrated to Gradle. I’m using:
- Gradle 8.13
- PMD 6.55.0
- A custom PMD rule which is packaged into a jar
- A ruleset xml which only includes the one single custom rule, no others
I have added config to my top level build.gradle, in my subprojects closure, to apply PMD currently just for one sub module, like this:
// Apply PMD plugin only to selected modules
if (project.name in ['my-module']) {
apply plugin: 'pmd'
dependencies {
// custom rules
pmd 'com.something:custom-pmd-rules:1.170-SNAPSHOT'
pmd files(projectDir)
}
pmd {
toolVersion = "6.55.0"
ruleSets = [] // clear default rule sets
ruleSetFiles = files("pmd-ruleset.xml")
consoleOutput = true
}
// disable pmdTest and pmdTestFixture tasks.
tasks.matching { task ->
task.name in ["pmdTest", "pmdTestFixtures"] }
.each { task ->
task.onlyIf { false }
}
// Run pmdMain task when property is specified. We'll run this on CI
tasks.matching { task ->
task.name.equals("pmdMain")}
.each { task ->
task.onlyIf { rootProject.hasProperty("runPMD") }
}
}
PMD runs, but I’m having some bad issues. It is taking 30 minutes to run on my Mac, without any tests, just PMD. Normally my whole build with 11,000 tests takes about 3 mins. So I suspect something is badly wrong, but I can’t even figure out how to run this via a debugger. If I configure Gradle for debugging, and to wait for a debugger on port 5005, yes it does that, but it never hits any breakpoints in PMD code or my custom rule. So I think it is forking a Gradle worker for PMD which is not passing on any JVM debug args?
If I look at the PMD task it extends from AbstractCodeQualityTask which has this code:
protected void configureForkOptions(JavaForkOptions forkOptions) {
forkOptions.setMinHeapSize((String)this.getMinHeapSize().getOrNull());
forkOptions.setMaxHeapSize((String)this.getMaxHeapSize().getOrNull());
forkOptions.setExecutable(((JavaLauncher)this.getJavaLauncher().get()).getExecutablePath().getAsFile().getAbsolutePath());
maybeAddOpensJvmArgs((JavaLauncher)this.getJavaLauncher().get(), forkOptions);
}
private static void maybeAddOpensJvmArgs(JavaLauncher javaLauncher, JavaForkOptions forkOptions) {
if (JavaVersion.toVersion(javaLauncher.getMetadata().getJavaRuntimeVersion()).isJava9Compatible()) {
forkOptions.jvmArgs(new Object[]{"--add-opens", "java.prefs/java.util.prefs=ALL-UNNAMED"});
}
}
I can’t see anything here related to passing debug args to a forked JVM, which is making me suspect a JVM is being forked, but without any debug settings. So I am just debugging the original Gradle JVM, not the one running PMD.
In my PMD output, I see a huge pause before any of my rule violations come up, with repeats of a worrying output:
Analysis cache loaded
Analysis cache updated
This repeats hundreds, if not thousands of times, which seems wrong!?
So my questions are:
- How can I run this in proper debug mode? Right now I’m thinking I will have to create a custom Java exec task rather than using the built in PMD plugin. Or is there a way to do it using the built in plugin?
- Anybody got any idea why the analysis cache is constantly loading and updating? Is this right or wrong?
- Config I could pass to the PMD task to enable more debug logging?