Table of Contents
12-September-2025 - 7.17.0
The PMD team is pleased to announce PMD 7.17.0.
This is a minor release.
π 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 missinghashCode()
and/orequals()
methods on types that implementComparable
. 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 theSet
interface. While theSet
interface relies onequals()
to determine object equality, sorted sets likeTreeSet
usecompareTo()
instead. The same issue can arise when such objects are used as keys in sorted maps.
This rule is very similar toOverrideBothEqualsAndHashcode
which has always been skippingComparable
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 ruleUnnecessaryLocalBeforeReturn
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 aString
from aCollection<Integer>
: although it is allowed to write this becauseremove
takes anObject
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 ofpublic static
). It ensures modifiers appear in the correct order as recommended by the Java Language Specification.
Deprecated Rules
- The java rule
GenericsNaming
has been deprecated for removal in favor of the new ruleTypeParameterNamingConventions
. - The java rule
AvoidLosingExceptionInformation
has been deprecated for removal in favor of the new ruleUselessPureMethodCall
. - The java rule
UselessOperationOnImmutable
has been deprecated for removal in favor of the new ruleUselessPureMethodCall
. - The java rule
UnnecessaryLocalBeforeReturn
has been deprecated for removal in favor of the new ruleVariableCanBeInlined
.
CPD: New Markdown Report Format
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
- java
- 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
- 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
- pmd-java:
JClassSymbol#annotationAppliesTo
: UseJClassSymbol#annotationAppliesToContext
instead.Experimental API
- pmd-core:
RuleContext#addViolationWithPosition
PMD Report Format CSV
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
- test
- The method
AbstractRuleSetFactoryTest#hasCorrectEncoding
will be removed. PMD has the ruleMissingEncoding
for XML files that should be used instead.
- The method
β¨ 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