Reputation: 10322
I've never used Gradle's PMD plugin and I'm running into trouble trying to add rule sets to my build.gradle
. The Pmd documentation is not clear about what the valid values of ruleSets
are. Their example is ruleSets = ["basic", "braces"]
and they link to the "official list". There's not much to go on, unfortunately.
I was guessing the section title maps to the valid string somehow? Like,
But what about things like "Empty Code (java)"?
Here's a working build.gradle
example:
apply plugin: 'java'
apply plugin: 'pmd'
pmd {
ruleSets = [
// The first two better work since it's right in the Javadoc...
"basic",
"braces",
// This one does not work and other variations like
// "empty code", "emptycode", "empty-code", "empty_code" do not work.
"emptyCode"
]
}
repositories {
mavenCentral()
}
Gradle spits out the following error:
$ gradle check :pmdMain FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':pmdMain'. > Can't find resource emptyCode. Make sure the resource is a valid file or URL or is on the CLASSPATH. Here's the current classpath: /Users/kuporific/gradle/gradle-1.10/lib/gradle-launcher-1.10.jar * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. BUILD FAILED Total time: 9.907 secs
Running with --stacktrace
or --debug
as suggested doesn't seem to yield anything useful...
Note: create a dummy file like src/main/java/Dummy.java
. Otherwise, the build will succeed.
How are ruleSets
supposed to be declared?
It ended up being easier declaring an xml
rule set because it offers fine-grained control over the rules. It is included in build.gradle
like so:
apply plugin: 'pmd'
pmd {
ruleSetFiles = files('path/to/ruleSet.xml')
}
And the rule set file looks something like this:
Note: This exaple is written for Gradle 1.10. Newer versions of Gradle (circa 2.0) use a newer version of PMD; therefore, many of the rulesets
paths changed. So rulesets/logging-java.xml
is now found in rulesets/java/logging-java.xml
, for example.
<?xml version="1.0" encoding="UTF-8"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
name="Android Application Rules"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0
http://pmd.sf.net/ruleset_xml_schema.xsd" >
<rule ref="rulesets/logging-java.xml" />
<rule ref="rulesets/basic.xml" />
<rule ref="rulesets/braces.xml" />
<rule ref="rulesets/codesize.xml" >
<exclude name="TooManyMethods" />
</rule>
<rule ref="rulesets/controversial.xml">
<exclude name="UseConcurrentHashMap" />
<exclude name="AvoidLiteralsInIfCondition" />
<exclude name="DataflowAnomalyAnalysis" />
<exclude name="CallSuperInConstructor" />
<exclude name="AtLeastOneConstructor" />
<exclude name="NullAssignment" />
</rule>
<!-- etc... -->
</ruleset>
Upvotes: 11
Views: 14148
Reputation: 49583
The latest version of PMD
(5.1.3
when writing this answer) is supported by gradle. The rulesets need to be prefixed by a java-
I tested this with gradle-1.12
To use PMD 5.1.3
with gradle, the following configuration defines all the possibles rulesets I could find:
pmd {
toolVersion = '5.1.3'
ruleSets = [
'java-android',
'java-basic',
'java-braces',
'java-clone',
'java-codesize',
'java-comments',
'java-controversial',
'java-coupling',
'java-design',
'java-empty',
'java-finalizers',
'java-imports',
'java-j2ee',
'java-javabeans',
'java-junit',
'java-logging-jakarta-commons',
'java-logging-java',
'java-migrating',
'java-naming',
'java-optimizations',
'java-strictexception',
'java-strings',
'java-sunsecure',
'java-typeresolution',
'java-unnecessary',
'java-unusedcode'
]
}
Upvotes: 20
Reputation: 2979
To add to the other excellent answers here. After applying pmd to your gradle build and invoking it via gradle pmdMain
, the pmd jar will be downloaded to your gradle cache. From there you can run:
find ~/.gradle -name "*pmd*.jar" -exec jar -tvf {} \;|grep rulesets
And you will get the output:
0 Thu Nov 10 20:48:06 EST 2011 rulesets/
0 Thu Nov 10 20:48:06 EST 2011 rulesets/internal/
0 Thu Nov 10 20:48:06 EST 2011 rulesets/releases/
18068 Thu Nov 10 20:48:06 EST 2011 rulesets/naming.xml
65 Thu Nov 10 20:48:06 EST 2011 rulesets/jsprulesets.properties
710 Thu Nov 10 20:48:06 EST 2011 rulesets/migrating_to_15.xml
483 Thu Nov 10 20:48:06 EST 2011 rulesets/migrating_to_14.xml
1048 Thu Nov 10 20:48:06 EST 2011 rulesets/rulesets.properties
3017 Thu Nov 10 20:48:06 EST 2011 rulesets/javabeans.xml
2089 Thu Nov 10 20:48:06 EST 2011 rulesets/sunsecure.xml
777 Thu Nov 10 20:48:06 EST 2011 rulesets/migrating_to_junit4.xml
3198 Thu Nov 10 20:48:06 EST 2011 rulesets/scratchpad.xml
13190 Thu Nov 10 20:48:06 EST 2011 rulesets/strings.xml
1379 Thu Nov 10 20:48:06 EST 2011 rulesets/internal/all-java.xml
2639 Thu Nov 10 20:48:06 EST 2011 rulesets/internal/dogfood.xml
6036 Thu Nov 10 20:48:06 EST 2011 rulesets/finalizers.xml
5347 Thu Nov 10 20:48:06 EST 2011 rulesets/logging-jakarta-commons.xml
13629 Thu Nov 10 20:48:06 EST 2011 rulesets/migrating.xml
610 Thu Nov 10 20:48:06 EST 2011 rulesets/migrating_to_13.xml
3593 Thu Nov 10 20:48:06 EST 2011 rulesets/braces.xml
4163 Thu Nov 10 20:48:06 EST 2011 rulesets/clone.xml
702 Thu Nov 10 20:48:06 EST 2011 rulesets/releases/33.xml
1332 Thu Nov 10 20:48:06 EST 2011 rulesets/releases/41.xml
1009 Thu Nov 10 20:48:06 EST 2011 rulesets/releases/35.xml
395 Thu Nov 10 20:48:06 EST 2011 rulesets/releases/43.xml
1340 Thu Nov 10 20:48:06 EST 2011 rulesets/releases/40rc1.xml
1110 Thu Nov 10 20:48:06 EST 2011 rulesets/releases/34.xml
537 Thu Nov 10 20:48:06 EST 2011 rulesets/releases/38.xml
346 Thu Nov 10 20:48:06 EST 2011 rulesets/releases/37-jsp.xml
393 Thu Nov 10 20:48:06 EST 2011 rulesets/releases/37.xml
744 Thu Nov 10 20:48:06 EST 2011 rulesets/releases/39.xml
1066 Thu Nov 10 20:48:06 EST 2011 rulesets/releases/36.xml
1256 Thu Nov 10 20:48:06 EST 2011 rulesets/releases/42.xml
6379 Thu Nov 10 20:48:06 EST 2011 rulesets/android.xml
4967 Thu Nov 10 20:48:06 EST 2011 rulesets/logging-java.xml
11557 Thu Nov 10 20:48:06 EST 2011 rulesets/j2ee.xml
52926 Thu Nov 10 20:48:06 EST 2011 rulesets/design.xml
9216 Thu Nov 10 20:48:06 EST 2011 rulesets/basic-jsp.xml
37773 Thu Nov 10 20:48:06 EST 2011 rulesets/basic.xml
3981 Thu Nov 10 20:48:06 EST 2011 rulesets/imports.xml
3836 Thu Nov 10 20:48:06 EST 2011 rulesets/typeresolution.xml
2755 Thu Nov 10 20:48:06 EST 2011 rulesets/unusedcode.xml
25043 Thu Nov 10 20:48:06 EST 2011 rulesets/controversial.xml
3045 Thu Nov 10 20:48:06 EST 2011 rulesets/coupling.xml
13379 Thu Nov 10 20:48:06 EST 2011 rulesets/strictexception.xml
12787 Thu Nov 10 20:48:06 EST 2011 rulesets/codesize.xml
12484 Thu Nov 10 20:48:06 EST 2011 rulesets/junit.xml
10784 Thu Nov 10 20:48:06 EST 2011 rulesets/optimizations.xml
1412 Thu Nov 10 20:48:06 EST 2011 rulesets/basic-jsf.xml
1396 Thu Nov 10 20:48:06 EST 2011 rulesets/favorites.xml
These may not all be implemented, but it is a good starting point. For a description of each file, you can check the documentation here.
Upvotes: 6
Reputation: 1919
I realize this is a huge edit, but it's essentially a different answer. So after speaking to you and playing around with it, I've determined that the Gradle plugin uses a slightly older version of the pmd library than is published (namely, version 4.3); however, there are a few rulesets missing from the plugin since the most recent pmd version is 5.0.5 which breaks with a NullPointerException
with Gradle and Java. Now, after writing possibly the most syntactically correct and painstaking Hello World Java program of my life to test all of these, I've compiled every single Java rule-set that works with the Gradle plugin at the moment:
here's the Main.java:
package william;
import java.util.logging.Logger;
public final class Main{
private Main(){}
public static void main(final String [ ] args){
final Logger log = Logger.getLogger(Main.class.getName());
log.fine("Hello World");
}
}
here's the build.gradle:
apply plugin: 'java'
apply plugin: 'pmd'
pmd {
ruleSets = [
"basic",
"braces",
"naming",
"android",
"clone",
"codesize",
"controversial",
"design",
"finalizers",
"imports",
"j2ee",
"javabeans",
"junit",
"logging-jakarta-commons",
"logging-java",
"migrating",
"optimizations",
"strictexception",
"strings",
"sunsecure",
"typeresolution",
"unusedcode"
]
}
repositories {
mavenCentral()
}
and now you might be wondering, which rulesets AREN'T supported yet? well the answer is:
"comments"
"empty"
"unnecessary"
Trust me when I say, the rest of the rules work flawlessly. They tore me apart when writing a Hello World. So, I hope this helps, the directory that has all of the Java rulesets.xml files defined is at: link to pmd's github java ruleset directory I ignore the migrate ones, because they didn't work. I think they're for something specific.
Good luck, and I would bring up the issue of the missing rulesets on the gradle forums to petition to get them added, or update the version. Or you could custom compile the plugin and link it to the newer pmd version if you are really desperate for the missing rulesets.
Upvotes: 6
Reputation: 5242
When using your own rulset.xml file as described by kuporific, like:
pmd {
ruleSetFiles = files('path/to/ruleSet.xml')
}
gradle 1.10 uses some kind of default rules. Yes it does complain if the filepath is wrong, yes it complains if the contents are invalid. But during the checks some default ruleset will be applied. So I'm kind of suprised this worked for you.
Workaround is not to use ruleSetfiles, but reference them one by one:
ruleSets = [ "$projectRoot/buildtools/pmd-rules/strings.xml"]
Upvotes: 1