/arch4u-pmd

Linting rules for Java frameworks like Spring, Quarkus, Jackson, SLF4J, etc., to avoid known problems in REST API, logging, observability, performance, and general best practices.

Primary LanguageJavaMIT LicenseMIT

Maven Javadocs License: MIT Commit activity Hits-of-Code

CI Known Vulnerabilities

Qulice Maintainability Rating codebeat badge Codacy Badge Codecov

Overview

arch4u-pmd is a library with pmd rules that bring new regulations related to known problems in REST API, logging, monitoring, etc., including reconfigured default pmd rules to decrease false-positive violations during usage of well-known frameworks like Spring, Quarkus, etc.

In addition to our custom/reconfigured rules we are using the latest stable pmd-java version which is 6.55.0 with more than 320+ rules with default configuration.

Legend:

  • βœ… included in arch4u-ruleset.xml
  • βŒ› planned for review considering framework(s) architecture
  • 🌡 temporary disabled or reconfigured in arch4u-ruleset.xml
  • ❌ disabled/not planned in arch4u-ruleset.xml
PMD rule Provider Status Spring Quarkus
UseExistingMediaTypeConstant arch4u-pmd:0.1.0 βœ… βœ… βŒ›
UseOpenApiInRestEndpoints arch4u-pmd:0.1.0 βœ… βœ… βŒ›
RestEndpointsWithoutExposedMetrics arch4u-pmd:0.1.0 βœ… βœ… βŒ›
UseConstantAsMetricName arch4u-pmd:0.1.0 βœ… βœ… βŒ›
NoMandatoryConstructorInExceptionClass arch4u-pmd:0.1.0 βœ… βœ… βŒ›
AvoidUsingObjectMapperAsALocalVariable arch4u-pmd:0.1.0 βœ… βœ… βŒ›
AvoidMdcOutsideTryStatement arch4u-pmd:0.1.0 βœ… βœ… βŒ›
PotentiallyThreadLocalPollutionByMdc arch4u-pmd:0.1.0 βœ… βœ… βŒ›
GuardLogStatement pmd-java:6.44.0 ❌ ❌ ❌
JUnitAssertionsShouldIncludeMessage pmd-java:6.44.0 🌡 βŒ› βŒ›
UnusedPrivateMethod pmd-java:6.44.0 🌡 βŒ› βŒ›
AtLeastOneConstructor pmd-java:6.44.0 🌡 βœ… βŒ›
OnlyOneReturn pmd-java:6.44.0 🌡 βŒ› βŒ›
CommentRequired pmd-java:6.44.0 🌡 βŒ› βŒ›
AvoidCatchingGenericException pmd-java:6.44.0 βŒ› βŒ› βŒ›
CouplingBetweenObjects pmd-java:6.44.0 🌡 βŒ› βŒ›
LawOfDemeter pmd-java:6.44.0 ❌ ❌ ❌
LoosePackageCoupling pmd-java:6.44.0 βŒ› βŒ› βŒ›
SignatureDeclareThrowsException pmd-java:6.44.0 βŒ› βŒ› βŒ›
TooManyFields pmd-java:6.44.0 🌡 βŒ› βŒ›
TooManyMethods pmd-java:6.44.0 🌡 βŒ› βŒ›
UseObjectForClearerAPI pmd-java:6.44.0 ❌ ❌ ❌
AtLeastOneConstructor pmd-java:6.44.0 ❌ ❌ ❌
UseUtilityClass pmd-java:6.44.0 🌡 βœ… βŒ›
ShortClassName pmd-java:6.44.0 🌡 βœ… βœ…
ImmutableField pmd-java:6.44.0 🌡 βœ… βœ…
LongVariable pmd-java:6.44.0 🌡 βœ… βœ…

How to use?

Maven (pom.xml)

...
<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/dgroup/arch4u/pmd/arch4u-ruleset.xml</ruleset>
         ...
       </rulesets>
       <excludeRoots>
         <excludeRoot>target/generated-sources/</excludeRoot>
       </excludeRoots>
     </configuration>
     <dependencies>
       <!-- Latest arch4u-rules -->
       <dependency>
         <groupId>io.github.dgroup</groupId>
         <artifactId>arch4u-pmd</artifactId>
         <version>${version}</version>
       </dependency>
     </dependencies>
   </plugin>
   ...
 </plugins>
</build>
 ...

Gradle (build.gradle)

apply plugin: 'pmd'

dependencies {
   ...
   pmd "io.github.dgroup:arch4u-pmd:${version}"    // use latest arch4u-pmd rules version
   pmd "commons-io:commons-io:2.11.0"              // required dependency by pmd engine
   ...
}

pmd {
   consoleOutput = true
   ruleSetFiles = files("io/github/dgroup/arch4u/pmd/arch4u-ruleset.xml")
   ruleSets = []                                   // Keep it as is, workaround for pmd
}

Include arch4u-pmd rules into your existing custom ruleset

  1. Don't forget to add rules to classpath in Maven/Gradle pmd plugin (see lines above)
  2. Let's assume that you already have pmd rules defined in your-pmd-ruleset.xml
  3. Add line <rule ref="io/github/dgroup/arch4u/pmd/arch4u-ruleset.xml"/> to your-pmd-ruleset.xml
    <?xml version="1.0"?>
    <ruleset name="pmd ruleset with your rules"
      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 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
     
      ...
      <rule ref="io/github/dgroup/arch4u/pmd/arch4u-ruleset.xml"/>
      ...
    
    </ruleset>

Exclude particular rule

<?xml version="1.0"?>
<ruleset name="pmd ruleset with your rules">
  ...
  <rule ref="io/github/dgroup/arch4u/pmd/arch4u-ruleset.xml">
    <exclude name="UseExistingMediaTypeConstant"/>
  </rule>
  ...
</ruleset>

Reconfigure a rule

<?xml version="1.0"?>
<ruleset name="pmd ruleset with your rules">
  ...
  <!-- 1. Exclude rule with default configuration  -->
  <rule ref="io/github/dgroup/arch4u/pmd/arch4u-ruleset.xml">
    <exclude name="UseExistingMediaTypeConstant"/>
  </rule>
  <!-- 2. Reconfigure rule with expected property -->
  <rule name="UseExistingMediaTypeConstant"
        language="java"
        externalInfoUrl="https://github.com/dgroup/arch4u-pmd/discussions/43"
        message="Use existing MediaType constant instead of string literal: https://github.com/dgroup/arch4u-pmd/discussions/43"
        class="io.github.dgroup.arch4u.pmd.UseExistingConstant">
    <priority>3</priority>
    <properties>
      <!-- 3. Set the 'regexPattern' considering your needs -->
      <property name="regexPattern" description="Regular expression of prohibited string"
                value="(^|\s)(application\/(json|xml|atom\+xml|x-www-form-urlencoded|octet-stream|svg\+xml|xhtml\+xml)|(multipart\/form-data)|(text\/(html|xml|plain)))(\s|$)"/>
    </properties>
  </rule>
  ...
</ruleset>

Exclude particular folder from inspection

<?xml version="1.0"?>
<ruleset name="pmd ruleset with your rules">
  ...
  <!-- Exclude target folder that may contain generated sources -->
  <exclude-pattern>.*/target/generated-sources/.*</exclude-pattern>
  <exclude-pattern>.*/build/generated-sources/.*</exclude-pattern>
  <!-- Exclude test folder -->
  <exclude-pattern>.*/src/test/java/org/tbd/tbd/tbd/.*</exclude-pattern>
  ...
</ruleset>

How to contribute?

  1. Pull requests are welcome! Don't forget to add your name to contribution section and run this, beforehand:
    mvn -Pqulice clean install
  2. Everyone interacting in this project’s codebases, issue trackers, chat rooms is expected to follow the code of conduct.
  3. Latest maven coordinates here:
    <dependency>
        <groupId>io.github.dgroup</groupId>
        <artifactId>arch4u-pmd</artifactId>
        <version>${version}</version>
    </dependency>
  4. Download pmd rule designer

Contributors