Do you ever find yourself struggling with code smells in your Java projects? You’re not alone! Code smells are simply indicators that your code could use some improvement. In this post, we'll explore how PMD (Programming Mistake Detector) can help you find and fix these pesky code smells effectively.
What Are Code Smells?
Code smells aren’t bugs, but they do suggest that your code could use some improvement to make it clearer, easier to maintain, or more efficient. Here are a few common examples:
- Long Methods: These are methods that are too long and try to do too many things at once.
- Duplicated Code: This is when you see the same code in several places.
- Deep Nesting: This happens when your code has too many nested blocks, making it tough to read.
What is PMD?
PMD (Programming Mistake Detector) is a handy tool that analyzes your source code to spot common programming issues. It helps identify things like unused variables, empty catch blocks, and overly complex methods, making it easier for you to improve your code quality.
Rulesets in PMD
PMD uses predefined rulesets to check your code. These rulesets have different rules that look for various kinds of issues. Here’s a quick look at some common rulesets:
- Basic: Looks for simple issues like empty catch blocks and unnecessary object creation.
- Design: Checks if your code follows good design principles and finds overly complex methods and classes.
- Unused Code: Finds code elements that are defined but never used.
How to Integrate PMD into Your Build Process
Integrating PMD into your build process helps you automatically check for code quality. Here’s how to set it up with Maven:
1. Add PMD Plugin to pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.21.0</version>
<configuration>
<rulesets>
<ruleset>java-basic</ruleset>
<ruleset>java-design</ruleset>
<ruleset>java-unusedcode</ruleset>
</rulesets>
</configuration>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>pmd</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Explanation:
-
<rulesets>
: This tells PMD which rulesets to use (like basic, design, and unused code). -
<phase>verify</phase>
: This sets PMD to run during the Mavenverify
phase, which happens after tests and before packaging your code.
2. Run PMD
You can run PMD during your Maven build or on its own.
-
During Build: PMD will run automatically during the
verify
phase when you run:
mvn clean verify
- Manually: If you want to run PMD separately, just use:
mvn pmd:pmd
This will kick off the PMD analysis.
3. View Reports
After PMD runs, it generates a report showing any issues it found.
- Locate the Report: You can find the PMD report at:
target/site/pmd.html
-
Report Contents:
- Summary: A quick overview of how many violations were found.
- Details: A list of issues, including file names, line numbers, and descriptions.
- Rulesets: Information about which rulesets were used and their results.
Example Walkthrough
Here’s a simple example to show PMD in action! You can check out the code in my Replit.
Consider the following code:
public class UnusedCode {
// This field is never used
private int unusedField;
public void usedMethod() {
System.out.println("This method is used.");
}
}
public class Main {
public static void main(String[] args) {
UnusedCode unusedCode = new UnusedCode();
}
}
After running mvn pmd:pmd
, you’ll find the report pmd.html
in the target/site/
folder.
If you open it in your browser, it will look something like this:
Understanding the PMD Report
- Overview: Displays the PMD version (6.55.0) and last published date.
-
Violations by Priority:
-
Main.java:
- Rule: UseUtilityClass
- Violation: "All methods are static. Consider using a utility class."
- Line: 1–5
-
UnusedCode.java:
- Rule: UnusedPrivateField
- Violation: "Avoid unused private fields."
- Line: 3
-
Main.java:
- Files Section: Details about violations for each analyzed file, highlighting areas for improvement.
Stopping Build Process if There Are Violations
When PMD finds errors during a Maven build, the build doesn’t stop by default. It will report the violations and keep going.
You can change this behavior so the build fails if certain limits of violations are hit. Here’s how:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.21.0</version>
<configuration>
<rulesets>
<ruleset>java-basic</ruleset>
<ruleset>java-design</ruleset>
<ruleset>java-unusedcode</ruleset>
</rulesets>
</configuration>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>pmd</goal>
<!-- Checks for violations and fails the build if found -->
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Explanation:
-
<goal>check</goal>
: This tells PMD to check for violations in the report. If any are found, it will fail the build.
Now, if you run mvn clean verify
, your build will stop if there are violations.
Before adding the check goal
,
After adding it,
Conclusion
By integrating PMD into your Java projects, you can automatically spot and fix code smells, making your code more maintainable and efficient.
Feel free to share your experiences with PMD or ask any questions in the comments below.
Happy coding! 😊
Top comments (4)
I guess PMD is a lightweight alternative for personal use, but if I want to build a solution for real-world project, I would probably favor SonarQube.
Thank you for your comment, @aloisseckar !
I don’t know much about SonarQube, but I’ll definitely check it out. Currently, I am using PMD to create custom rules in Java. Does SonarQube offer similar functionality?
Docs show couple of ways docs.sonarsource.com/sonarqube/lat...
Thanks for the link 😊! I’ll check out the docs.