Search code examples
javamavengradlepmd

How can we have different PMD rulesets in Maven for the main and test java code sets?


In Gradle, we can specify different PMD configurations (including different rulesets) for the pmdMain and pmdTest source sets. e.g.

pmdMain {
    ruleSetFiles = files("$javaBuildSystemRoot/src-pmd-rulesets.xml")
}

pmdTest {
    ruleSetFiles = files("$javaBuildSystemRoot/test-pmd-rulesets.xml")
}

We want to be less stringent on test code than main code.

There is a separate maven based project, where we cannot use gradle currently.But for now, we would like to at least apply the 2 different rulesets based on main vs test. It is a single module single project, using the maven PMD plugin.

How do we do this in the Maven pom file?


Solution

  • It is "rather unconventional" to pmd over test sources, but that is not part of the question. :)

    Using the executions tag and utilizing maven-pmd-plugin, you can do this with maven.


    EDIT: In short & applied to the given input (and maybe more than you wanted/need), it enables/forces you to make both checks in every build:

    <project><build><plugins>
    <plugin>
        <artifactId>maven-pmd-plugin</artifactId>
        <version>3.11.0</version> <!-- latest up-to-date -->
        <executions>
           <execution>
               <id>pmd-execution</id>
               <goals>
                   <goal>check</goal>
               </goals>
               <configuration>
                   <rulesets>
                       <ruleset>/path/to/.../src-pmd-rulesets.xml</ruleset>
                   </rulesets>
               </configuration>
          </execution>
          <execution>
               <id>pmd-test-execution</id>
               <goals>
                  <goal>check</goal>
               </goals>
               <configuration>
                   <includeTests>true</includeTests> <!-- this defaults to false! -->
                   <rulesets>
                       <ruleset>/path/to/.../test-pmd-rulesets.xml</ruleset>
                   </rulesets>
               </configuration>
            </execution>
        </executions>
    </plugin>
    ...
    

    See also: Can I configure multiple plugin executions in pluginManagement, and choose from them in my child POM?


    EDIT 2: If you indeed don't need "both executions" (in 1 build), but only "two configurations" for "different builds", then: Maven Profiles fits your needs (with profiles ... your "possibilities converge to infinity") !

    You would introduce profiles like:

     <project>
     ...
     <profiles>
       <profile>
         <id>pmdMain</id>
         <properties>
             <myPmdRuleSetLocation>/path/to/.../src-pmd-rulesets.xml</myPmdRuleSetLocation>
             <myPmdTestsInclude>false</myPmdTestsInclude>
         </properties>
       </profile> 
       <profile>
         <id>pmdTest</id>
         <properties>
             <myPmdRuleSetLocation>/path/to/.../test-pmd-rulesets.xml</myPmdRuleSetLocation>
             <myPmdTestsInclude>true</myPmdTestsInclude>
         </properties>
       </profile> 
     <profiles>
     ...
     </project>
    

    And use it in your (single execution) pmd-plugin configuration:

    ...
      <ruleset>${myPmdRuleSetLocation}</ruleset>
      <includeTests>${myPmdTestsInclude}</includeTests>
    ...
    

    Please read further on profiles and their activation.

    (additionally <profile/> can contain & override <build/> tag!)