I'm using the built-in rulesets strings.xml
and unusedcode.xml
with
<?xml version="1.0"?>
<ruleset name="Custom ruleset"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
The default ruleset
</description>
<rule ref="rulesets/java/strings.xml"/>
<rule ref="rulesets/java/unusedcode.xml"/>
</ruleset>
in the maven-pmd-plugin
as follows:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.8</version>
<executions>
<execution>
<id>pmd-check</id>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<printFailingErrors>true</printFailingErrors>
<detail>true</detail>
<rulesets>
<ruleset>${basedir}/src/main/resources/ruleset.xml</ruleset>
</rulesets>
</configuration>
</plugin>
So that I get the following problem in the following use case:
public class NewClass { private final static String PMD_UNUSED_FORMAL_PARAMETER = "PMD.UnusedFormalParameter"; @SuppressWarnings(PMD_UNUSED_FORMAL_PARAMETER) private void someMethod1(Object parameter1) { System.out.println("someMethod1"); } @SuppressWarnings("PMD.UnusedFormalParameter") private void someMethod2(Object parameter1) { System.out.println("someMethod2"); } @SuppressWarnings("PMD.UnusedFormalParameter") private void someMethod3(Object parameter1) { System.out.println("someMethod3"); } @SuppressWarnings("PMD.UnusedFormalParameter") private void someMethod4(Object parameter1) { System.out.println("someMethod4"); } public static void main(String[] args) { NewClass newClazz = new NewClass(); newClazz.someMethod1(null); newClazz.someMethod2(null); newClazz.someMethod3(null); } }
Having the annotation parameter value "PMD.UnusedFormalParameter"
appear 4 times causes an AvoidDuplicateLiterals
violation. replacing the string with the commented out private final static
constant causes the annotation to have no effect and thus an UnusedFormalParameter
violation.
I don't know about the internals of PMD. As an out-of-the-box user it appears strange that PMD both doesn't substitute the variable with its value (even though that's probably a context sensitive task it should be possible within the scope of static code analysis, it's just complex) and that UnusedFormalParameter
doesn't exclude string values which are obviously used to suppress other checks and are only there because of PMD.
I'm using maven-pmd-plugin
3.8.
As for your issue, there are currently 2 ways you can work around this:
AvoidDuplicateLiterals
allows for a skipAnnotations
property that can be set to true
to ignore literals in annotations. Of course that would ignore all literals in all annotations, not just @SuppressWarnings
violationSuppressXPath
property with an XPath expression of expressions to ignore. For instance, on this case, you can set it to the AvoidDuplicateLiterals
rule to ignore literals on @SuppressWarnings
. I believe the proper expression for this would be //Annotation//Name[@Image = "SuppressWarnings" or @Image = "java.lang.SuppressWarnings"]/..//Literal
(you'd have to test it to make sure)I don't know about the internals of PMD. As an out-of-the-box user it appears strange that PMD both doesn't substitute the variable with its value (even though that's probably a context sensitive task it should be possible within the scope of static code analysis, it's just complex)
You are right, this behavior is not currently supported. I've just added an issue on Github to track the request. Feel free to chip in.