Table of Contents
The Gradle Build Tool provides a PMD Plugin that can be added to your build configuration. Technically it is based on the Ant Task.
Example
In your build.gradle add the following:
plugins {
id 'pmd'
}
Custom ruleset
Configuration of a custom ruleset looks like this:
pmd {
ruleSetFiles = files("custom-pmd-ruleset.xml")
ruleSets = []
}
Note: The ruleSets array is explicitly set to empty to avoid using the default configuration.
Fail the build
If you want to fail the build for pmd violations, you need to set ignoreFailures:
pmd {
ignoreFailures = false
}
More configuration options are documented on PMD Extension.
Upgrade PMD version
If you want to use a newer PMD version than the default one provided with Gradle, you can do so
with the property toolVersion:
pmd {
toolVersion = "7.29.0-SNAPSHOT"
}
Note
For PMD 7, at least Gradle 8.6 is needed. See Support for PMD 7.0.
Aux Classpath
Gradle by default adds all project dependencies to the aux classpath. Since PMD 7.27.0, you’ll get a warning if the platform classes will be resolved by the running JVM. To avoid this, explicitly add the platform classpath of the correct Java version to PMD’s aux classpath. The example is using the toolchains feature of Gradle:
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
// Add jrt-fs.jar of the toolchain explicitly on pmdAux classpath, to avoid
// warning "Adding current platform ... to auxClasspath, which could be the wrong java version."
dependencies {
pmdAux javaToolchains.launcherFor(java.toolchain)
.map { it.metadata.installationPath }
.map { it.files("lib/jrt-fs.jar")}
}
See Providing the auxiliary classpath.
Environment Variables
Environment variables are not automatically passed through to Gradle’s PMD Plugin. E.g. using any Language properties with Gradle is not straight forward, as PMD is called in an isolated worker process without any environment variables.
The following snippets creates a subclass of Gradle’s PMD task in order to provide all PMD specific environment variables. This task needs to be registered and the default tasks “pmdMain” and “pmdTest” need to be disabled.
abstract class PmdWithEnv extends Pmd {
@Input
abstract MapProperty<String, String> getPmdEnvironment()
@Override
protected void configureForkOptions(JavaForkOptions forkOptions) {
super.configureForkOptions(forkOptions)
forkOptions.environment(pmdEnvironment.get())
}
}
tasks.named('pmdMain') {
enabled = false
}
tasks.register('pmdMainEnv', PmdWithEnv) {
source = pmdMain.source
classpath = pmdMain.classpath
pmdEnvironment.convention(providers.environmentVariablesPrefixedBy('PMD_'))
}
tasks.named('pmdTest') {
enabled = false
}
tasks.register('pmdTestEnv', PmdWithEnv) {
source = pmdTest.source
classpath = pmdTest.classpath
pmdEnvironment.convention(providers.environmentVariablesPrefixedBy('PMD_'))
}
tasks.named('check') {
dependsOn tasks.withType(PmdWithEnv)
}
With that configuration, you can call Gradle like that:
PMD_JAVA_DISABLE_AUX_CLASSPATH_WARNINGS=true ./gradlew check
Complete Example
See https://github.com/pmd/pmd-examples/tree/main/gradle/simple-project.
References
Source code for Gradle’s PMD Plugin is available here:
- gradle/gradle code-quality
- The default PMD version used by Gradle 9.7.1: DEFAULT_PMD_VERSION