PMD 7.17.0 released
12 September 2025
12-September-2025 - 7.17.0
The PMD team is pleased to announce PMD 7.17.0.
This is a minor release.
Table Of Contents
🚀 New and noteworthy
✨ New Rules
This release brings several new rules for both Java and Apex. Please try them out
and submit feedback on our issue tracker!
- The new apex rule
AnnotationsNamingConventions
enforces that annotations
are used consistently in PascalCase.
The rule is referenced in the quickstart.xml ruleset for Apex.
- The new java rule
TypeParameterNamingConventions
replaces the now deprecated rule
GenericsNaming. The new rule is configurable and checks for naming conventions of type parameters in
generic types and methods. It can be configured via a regular expression.
By default, this rule uses the standard Java naming convention (single uppercase letter).
The rule is referenced in the quickstart.xml ruleset for Java.
- The new java rule
OverrideBothEqualsAndHashCodeOnComparable
finds missing
hashCode()
and/or equals()
methods on types that implement Comparable
. This is important if
instances of these classes are used in collections. Failing to do so can lead to unexpected behavior in sets
which then do not conform to the Set
interface. While the Set
interface relies on
equals()
to determine object equality, sorted sets like TreeSet
use
compareTo()
instead. The same issue can arise when such objects are used
as keys in sorted maps.
This rule is very similar to OverrideBothEqualsAndHashcode
which has always been
skipping Comparable
and only reports if one of the two methods is missing. The new rule will also report,
if both methods (hashCode and equals) are missing.
The rule is referenced in the quickstart.xml ruleset for Java.
- The new java rule
UselessPureMethodCall
finds method calls of pure methods
whose result is not used. Ignoring the result of such method calls is likely as mistake as pure
methods are side effect free.
The rule is referenced in the quickstart.xml ruleset for Java.
- The new java rule
RelianceOnDefaultCharset
finds method calls that
depend on the JVM’s default charset. Using these method without specifying the charset explicitly
can lead to unexpected behavior on different platforms.
- Thew new java rule
VariableCanBeInlined
finds local variables that are
immediately returned or thrown. This rule replaces the old rule UnnecessaryLocalBeforeReturn
which only considered return statements. The new rule also finds unnecessary local variables
before throw statements.
The rule is referenced in the quickstart.xml ruleset for Java.
- The new java rule
CollectionTypeMismatch
detects calls to
collection methods where we suspect the types are incompatible. This happens for instance
when you try to remove a String
from a Collection<Integer>
: although it is allowed
to write this because remove
takes an Object
parameter, it is most likely a mistake.
This rule is referenced in the quickstart.xml ruleset for Java.
- The new java rule
DanglingJavadoc
finds Javadoc comments that
do not belong to a class, method or field. These comments are ignored by the Javadoc tool
and should either be corrected or removed.
The rule is referenced in the quickstart.xml ruleset for Java.
- The new java rule
ModifierOrder
(codestyle
) finds incorrectly ordered modifiers
(e.g., static public
instead of public static
). It ensures modifiers appear in the correct order as
recommended by the Java Language Specification.
Deprecated Rules
This PMD version ships with a simple Markdown based output format for CPD. It outputs all duplications
one after another including the code snippets as code blocks.
See Report formats for CPD.
🐛 Fixed Issues
- apex-codestyle
- #5650: [apex] New Rule: AnnotationsNamingConventions
- core
- #4721: [core] chore: Enable XML rule MissingEncoding in dogfood ruleset
- #5849: [core] Support Markdown Output for CPD Reports
- #5958: [core] CSVRenderer: Add begin and end for line and columns (default off)
- java
- #5874: [java] Update java regression tests with Java 25 language features
- #5960: [java] Avoid/reduce duplicate error messages for some rules
- #6014: [java] Crash when encountering a java comment at the end of a file
- java-bestpractices
- #2186: [java] New Rule: RelianceOnDefaultCharset
- #4500: [java] AvoidReassigningLoopVariables - false negatives within for-loops and skip allowed
- #4770: [java] UnusedFormalParameter should ignore public constructor as same as method
- #5198: [java] CheckResultSet false-positive with local variable checked in a while loop
- java-codestyle
- #972: [java] Improve naming conventions rules
- #4916: [java] UseExplicitTypes: cases where ‘var’ should be unobjectionable
- #5601: [java] New Rule: ModifierOrder
- #5770: [java] New Rule: VariableCanBeInlined: Local variables should not be declared and then immediately returned or thrown
- #5922: [java] New Rule: TypeParameterNamingConventions
- #5948: [java] UnnecessaryBoxing false positive when calling
List.remove(int)
- #5982: [java] More detailed message for the UselessParentheses rule
- java-design
- #4911: [java] AvoidRethrowingException should allow rethrowing exception subclasses
- #5023: [java] UseUtilityClass implementation hardcodes a message instead of using the one defined in the XML
- java-documentation
- #5916: [java] New Rule: DanglingJavadoc
- java-errorprone
- #3401: [java] Improve AvoidUsingOctalValues documentation
- #3434: [java] False negatives in AssignmentInOperand Rule
- #5837: [java] New Rule: OverrideBothEqualsAndHashCodeOnComparable
- #5881: [java] AvoidLosingExceptionInformation does not trigger when inside if-else
- #5907: [java] New Rule: UselessPureMethodCall
- #5915: [java] AssignmentInOperand not raised when inside do-while loop
- #5949: [java] New Rule: CollectionTypeMismatch: for Collections methods that take Object as a parameter
- #5974: [java] CloseResourceRule: NullPointerException while analyzing
- test
- #5973: [test] Enable XML validation for rule tests
🚨 API Changes
Deprecations
The CSV report format for PMD as three new columns:
- End Line
- Begin Column
- End Column
These columns are not enabled by default, but can be activated via their respective renderer properties.
See Report formats for PMD.
Rule Test Schema
When executing rule tests, the rule test XML file will be validated against the schema and the tests will fail
if the XML file is invalid.
There was a small bug in the schema around verifying suppressed violations: If a test wanted to verify, that there
are no suppressed violations, then this was not possible. Now the <expected-suppression>
element may be
empty. This is available in version 1.1.1 of the schema.
See Testing your rules for more information.
Deprecations
✨ Merged pull requests
- #5601: [java] New Rule: ModifierOrder - Clément Fournier (@oowekyala)
- #5822: [apex] Fix #5650: New Rule: AnnotationsNamingConventions - Mitch Spano (@mitchspano)
- #5847: [java] Fix #5770: New Rule: VariableCanBeInlined - Vincent Potucek (@Pankraz76)
- #5856: [java] Fix #5837: New Rule: OverrideBothEqualsAndHashCodeOnComparable - Vincent Potucek (@Pankraz76)
- #5907: [java] New Rule: UselessPureMethodCall - Zbynek Konecny (@zbynek)
- #5916: [java] New Rule: DanglingJavadoc - Zbynek Konecny (@zbynek)
- #5922: [java] Fix #972: Add a new rule TypeParameterNamingConventions - UncleOwen (@UncleOwen)
- #5924: [java] Fix #5915: Fix AssignmentInOperandRule to also work an do-while loops and switch statements - UncleOwen (@UncleOwen)
- #5930: [java] Fix #4500: Fix AvoidReassigningLoopVariablesRule to allow only simple assignments in the forReassign=skip case - UncleOwen (@UncleOwen)
- #5931: [java] Fix #5023: Fix UseUtilityClassRule to use the message provided in design.xml - UncleOwen (@UncleOwen)
- #5932: [ci] Reuse GitHub Pre-Releases - Andreas Dangel (@adangel)
- #5933: [test] Fix QuickstartRulesetTests to detect deprecated rules again - Andreas Dangel (@adangel)
- #5934: [java] Fix #2186: New Rule: RelianceOnDefaultCharset - UncleOwen (@UncleOwen)
- #5938: [doc] Update suppression docs to reflect PMD 7 changes - Zbynek Konecny (@zbynek)
- #5939: [java] Fix #5198: CheckResultSet FP when local variable is checked - Lukas Gräf (@lukasgraef)
- #5954: [core] Fix #4721: Enable XML rule MissingEncoding in dogfood ruleset - Andreas Dangel (@adangel)
- #5955: chore: Fix LiteralsFirstInComparison violations in test code - Andreas Dangel (@adangel)
- #5957: [java] Fix #3401: Improve message/description/examples for AvoidUsingOctalValues - UncleOwen (@UncleOwen)
- #5958: [core] CSVRenderer: Add begin and end for line and columns (default off) - Jude Pereira (@judepereira)
- #5959: [java] Fix #5960: AddEmptyString: Improve report location - Zbynek Konecny (@zbynek)
- #5961: [java] Fix #5960: Add details to the error message for some rules - Zbynek Konecny (@zbynek)
- #5965: [java] Fix #5881: AvoidLosingException - Consider nested method calls - Andreas Dangel (@adangel)
- #5967: [doc][java] ReplaceJavaUtilDate - improve doc to mention java.sql.Date - Andreas Dangel (@adangel)
- #5968: [doc] Add logging page to sidebar under dev docs - Andreas Dangel (@adangel)
- #5969: [doc] Add CSS in PMD’s description - Andreas Dangel (@adangel)
- #5970: chore: CI improvements - Andreas Dangel (@adangel)
- #5971: [java] Fix #5948: UnnecessaryBoxingRule: Check if unboxing is required for overload resolution - UncleOwen (@UncleOwen)
- #5972: [java] Fix #3434: False negatives in AssignmentInOperand rule - UncleOwen (@UncleOwen)
- #5975: [test] Fix #5973: Enable XML Validation for rule tests - Andreas Dangel (@adangel)
- #5979: [java] Fix #5974: NPE in CloseResourceRule - Lukas Gräf (@lukasgraef)
- #5980: chore: Fix typos - Zbynek Konecny (@zbynek)
- #5981: [java] Fix #4911: AvoidRethrowingException consider supertypes in following catches - UncleOwen (@UncleOwen)
- #5982: [java] More detailed message for the UselessParentheses rule - Zbynek Konecny (@zbynek)
- #5989: [java] Improve performance of RelianceOnDefaultCharset - UncleOwen (@UncleOwen)
- #5994: [java] Fix #4770: UnusedFormalParameter should ignore public constructor as same as method - UncleOwen (@UncleOwen)
- #5995: [html] Add test case that tests the end of a reported violation (test for #3951) - UncleOwen (@UncleOwen)
- #5996: [java] Fix #4916: UseExplicitTypes cases where ‘var’ should be unobjectionable - UncleOwen (@UncleOwen)
- #6006: [java] Fix #5949: New Rule: CollectionTypeMismatch - UncleOwen (@UncleOwen)
- #6008: [core] Fix #5849: Support Markdown Output for CPD Reports - Lukas Gräf (@lukasgraef)
- #6009: [java] More detailed message for AvoidInstanceofChecksInCatchClause - Zbynek Konecny (@zbynek)
- #6016: [java] Fix #6014: Crash when encountering a java comment at the end of a file - UncleOwen (@UncleOwen)
📦 Dependency updates
- #5936: Bump PMD from 7.15.0 to 7.16.0
- #5937: Bump pmdtester from 1.5.5 to 1.6.0
- #5941: chore(deps): bump org.apache.commons:commons-text from 1.13.1 to 1.14.0
- #5944: chore(deps): bump io.github.apex-dev-tools:apex-ls_2.13 from 5.9.0 to 5.10.0
- #5945: chore(deps): bump org.junit:junit-bom from 5.13.3 to 5.13.4
- #5946: chore(deps): bump org.apache.groovy:groovy from 4.0.27 to 4.0.28
- #5962: chore(deps): bump scalameta.version from 4.13.8 to 4.13.9
- #5963: chore(deps-dev): bump org.apache.commons:commons-compress from 1.27.1 to 1.28.0
- #5976: chore(deps-dev): bump all-contributors-cli from 6.20.0 to 6.26.1
- #5978: chore(deps-dev): bump org.assertj:assertj-core from 3.27.3 to 3.27.4
- #5984: chore(deps): bump actions/checkout from 4.2.2 to 5.0.0
- #5985: chore(deps): bump ruby/setup-ruby from 1.254.0 to 1.255.0
- #5986: chore(deps): bump actions/create-github-app-token from 2.0.6 to 2.1.1
- #5988: chore(deps): Bump build-tools from 33 to 34
- #5990: chore(deps): Update @babel/runtime from 7.16.7 to 7.28.7
- #5991: chore(deps): Update tmp from 0.0.33 to 0.2.5
- #5997: chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.17.6 to 1.17.7
- #5998: chore(deps): bump kotlin.version from 2.2.0 to 2.2.10
- #5999: chore(deps): bump org.mockito:mockito-core from 5.18.0 to 5.19.0
- #6000: chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.17.6 to 1.17.7
- #6001: chore(deps): bump com.google.protobuf:protobuf-java from 4.31.1 to 4.32.0
- #6002: chore(deps): bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.2 to 3.11.3
- #6013: chore(deps): bump actions/setup-java from 4.7.1 to 5.0.0
- #6033: chore(deps): bump ruby/setup-ruby from 1.255.0 to 1.257.0
- #6044: chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.1.0.4751 to 5.2.0.4988
- #6045: chore(deps): bump org.jetbrains:annotations from 26.0.2 to 26.0.2-1
- #6046: chore(deps): bump org.apache.groovy:groovy from 4.0.28 to 5.0.0
- #6047: chore(deps): bump org.yaml:snakeyaml from 2.4 to 2.5
- #6048: chore(deps): bump org.codehaus.mojo:versions-maven-plugin from 2.18.0 to 2.19.0
- #6049: chore(deps): bump org.jsoup:jsoup from 1.21.1 to 1.21.2
- #6050: chore(deps): bump bigdecimal from 3.2.2 to 3.2.3 in /docs
📈 Stats
- 188 commits
- 65 closed tickets & PRs
- Days since last release: 49