0

During working on project arch4u-pmd we made several java-based pmd rules, configured them in XML-based ruleset our-rules.xml, and published it as a plain java lib/artifact (io.github.abc:my-pmd-rules:0.1.0) to our artifacts repository. The artifact structure looks like this:

> unzip -l my-pmd-rules-0.1.0.jar   
Archive:  my-pmd-rules-0.1.0.jar   
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  02-15-2022 00:24   META-INF/
      139  02-15-2022 00:24   META-INF/MANIFEST.MF
        0  02-15-2022 00:24   io/
        0  02-15-2022 00:24   io/github/
        0  02-15-2022 00:24   io/github/rules/
        ...
     4781  02-15-2022 00:24   io/github/rules/MissingMandatoryAnnotation.class
     ...
     1138  02-15-2022 00:24   io/github/rules/our-rules.xml
     ...

How we can add them to the Gradle project using pmd plugin?

We have to process the following materials/questions/answers:

  1. https://stackoverflow.com/search?page=2&tab=Relevance&q=pmd%20classpath
  2. ClassNotFoundException: Using custom java rule for PMD ruleset
  3. Gradle's PMD plugin: what are acceptable arguments?
  4. Adding a ruleset to PMD?
  5. Adding custom rules in PMD - class not found issue
  6. https://discuss.gradle.org/t/pmd-ruleset-not-available-in-classpath/7201
  7. https://discuss.gradle.org/t/custom-rules-with-pmd-plugin/5859/4
  8. How to configure PMD Auxiliary classpath in Sonar
  9. https://docs.gradle.org/current/userguide/pmd_plugin.html
  10. https://github.com/gradle/gradle/blob/master/subprojects/code-quality/src/main/groovy/org/gradle/api/plugins/quality/PmdPlugin.java
  11. Custom PMD rule with Gradle also don't work
    tasks.withType(Pmd) {
       pmdClasspath += file("path/to/rules.jar")
    }
    
lazylead
  • 1,453
  • 1
  • 14
  • 26

1 Answers1

2

In official docs for Gradle pmd plugin there is a dependency section that explains this aspect on high-level without a real example:

  1. pmd - The PMD libraries to use
  2. pmdAux - The additional libraries that are available for type resolution during analysis. This might be useful if PMD complains about missing classes.

In order to add the custom java rules to your project

  1. Using Gradle plugin

    apply plugin: 'pmd'
    
    repositories {
       mavenCentral() // if your rules in Maven Central
       mavenLocal()   // if your rules is in .m2 folder 
       maven {
          // if your rules are in some custom/self-hosted artifacts repository like Nexus
       }
    }
    
    dependencies {
       ...
       pmd "io.github.abc:my-pmd-rules:0.1.0" 
       pmd "commons-io:commons-io:2.11.0"     // required dependency by pmd engine
       ...
    }
    
    pmd {
       consoleOutput = true
       ruleSetFiles = files("io/github/rules/our-rules.xml")    // exactly path as in your lib classpath
       ruleSets = []                                            // Keep it as is, workaround for pmd
    }
    
  2. Using Maven plugin

    ...
    <build>
     <plugins>
       ...
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-pmd-plugin</artifactId>
         <version>3.15.0</version>
         <executions>
           <execution>
             <phase>test</phase>
             <goals>
               <goal>check</goal>
             </goals>
           </execution>
         </executions>
         <configuration>
           <printFailingErrors>true</printFailingErrors>
           <rulesets>
             ...
             <ruleset>io/github/rules/our-rules.xml</ruleset> <!-- exactly path as in your lib classpath -->
             ...
           </rulesets>
           <excludeRoots>
             <excludeRoot>target/generated-sources/</excludeRoot>
           </excludeRoots>
         </configuration>
         <dependencies>
           <!-- your custom rules -->
           <dependency>
             <groupId>io.github.abc</groupId>
             <artifactId>my-pmd-rules</artifactId>
             <version>0.1.0</version>
           </dependency>
         </dependencies>
       </plugin>
       ...
     </plugins>
    </build>
     ...
    
  3. In case if you already have a ruleset and you just want to include the custom Java rule (that came from the library) you may define it directly in your ruleset xml as is:

      <!-- Define a rule -->
      <rule name="TheRuleName"
            language="java"
            externalInfoUrl="https://link.to.your.rule.official.docs.com"
            message="The violation message regarding your rule"
            class="io.github.rules.MissingMandatoryAnnotation">
        <priority>3</priority>
        <properties>
           ...
        </properties>
      </rule>
    
lazylead
  • 1,453
  • 1
  • 14
  • 26