| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| pmd-dist-7.21.0-bin.zip.asc | 2026-01-30 | 833 Bytes | |
| pmd-dist-7.21.0-doc.zip.asc | 2026-01-30 | 833 Bytes | |
| pmd-dist-7.21.0-src.zip.asc | 2026-01-30 | 833 Bytes | |
| pmd-dist-7.21.0-doc.zip | 2026-01-30 | 9.6 MB | |
| ReadMe.md | 2026-01-30 | 21.3 kB | |
| pmd-dist-7.21.0-src.zip | 2026-01-30 | 14.8 MB | |
| pmd-7.21.0-cyclonedx.json | 2026-01-30 | 305.4 kB | |
| pmd-dist-7.21.0-bin.zip | 2026-01-30 | 72.9 MB | |
| pmd-7.21.0-cyclonedx.xml | 2026-01-30 | 282.0 kB | |
| Totals: 9 Items | 97.9 MB | 25 | |
30-January-2026 - 7.21.0
The PMD team is pleased to announce PMD 7.21.0.
This is a minor release.
Table Of Contents
- 🚀️ New and noteworthy
- 🌟️ New and Changed Rules
- 🐛️ Fixed Issues
- 🚨️ API Changes
- ✨️ Merged pull requests
- 📦️ Dependency updates
- 📈️ Stats
🚀️ New and noteworthy
🚀️ New: Java 26 Support
This release of PMD brings support for Java 26.
There are no new standard language features.
There is one preview language feature:
In order to analyze a project with PMD that uses these preview language features,
you'll need to select the new language version 26-preview:
pmd check --use-version java-26-preview ...
Note: Support for Java 24 preview language features have been removed. The version "24-preview" is no longer available.
Build Requirement is Java 21
From now on, Java 21 or newer is required to build PMD. PMD itself still remains compatible with Java 8, so that it still can be used in a pure Java 8 environment. This allows us to use the latest checkstyle version during the build.
CPD
- The Apex module now supports suppression through
CPD-ON/CPD-OFFcomment pairs. See #6417
🌟️ New and Changed Rules
New Rules
- The new Java rule
PublicMemberInNonPublicTypedetects public members (such as methods or fields) within non-public types. Non-public types should not declare public members, as their effective visibility is limited, and using thepublicmodifier can create confusion. - The new Java rule
UnsupportedJdkApiUsageflags the use of unsupported and non-portable JDK APIs, includingsun.*packages,sun.misc.Unsafe, andjdk.internal.misc.Unsafe. These APIs are unstable, intended for internal use, and may change or be removed. The rule complements Java compiler warnings by highlighting such usage during code reviews and encouraging migration to official APIs like VarHandle and the Foreign Function & Memory API.
Changed Rules
The following rules have been changed to use a consistent implementation of enum based rule properties:
- The property
checkAddressTypesof ruleAvoidUsingHardCodedIPhas changed: - Instead of
IPv4useipv4 - Instead of
IPv6useipv6 - Instead of
IPv4 mapped IPv6useipv4MappedIpv6 - The old values still work, but you'll see a deprecation warning.
- The property
nullCheckBranchof ruleConfusingTernaryhas changed: - Instead of
Anyuseany - Instead of
Thenusethen - Instead of
Elseuseelse - The old values still work, but you'll see a deprecation warning.
- The property
typeAnnotationsof ruleModifierOrderhas changed: - Instead of
ontypeuseonType - Instead of
ondecluseonDecl - The old values still work, but you'll see a deprecation warning.
- The values of the properties of rule
CommentRequiredhave changed: - Instead of
Requireduserequired - Instead of
Ignoreduseignored - Instead of
Unwanteduseunwanted - The old values still work, but you'll see a deprecation warning.
Deprecated Rules
- The Java rule
DontImportSunhas been deprecated. It is replaced byUnsupportedJdkApiUsage.
🐛️ Fixed Issues
- core
- #6184: [core] Consistent implementation of enum properties
- apex
- #6417: [apex] Support CPD suppression with "CPD-OFF" & "CPD-ON"
- apex-codestyle
- #6349: [apex] FieldDeclarationsShouldBeAtStart: False positive with properties
- cli
- #6290: [cli] Improve Designer start script
- java
- #5871: [java] Support Java 26
- #6364: [java] Parse error with yield lambda inside switch
- java-design
- #6231: [java] New Rule: PublicMemberInNonPublicType
- java-errorprone
- #3601: [java] InvalidLogMessageFormat: False positive when final parameter is Supplier<Throwable>
- #5882: [java] UnconditionalIfStatement: False negative when true/false is not literal but local variable
- #5923: [java] New Rule: Catch usages of sun.misc.Unsafe or jdk.internal.misc.Unsafe
- java-performance
- #3857: [java] InsufficientStringBufferDeclaration: False negatives with String constants
🚨️ API Changes
Deprecations
- core
MetricOption#valueName: When metrics are used for (rule) properties, then the conventional enum mapping (from SCREAMING_SNAKE_CASE to camelCase) will be used for the enum values. SeeconventionalEnumListProperty.- In
PropertyFactory:enumProperty(String, Map). UseconventionalEnumPropertyinstead.enumProperty(String, Class). UseconventionalEnumPropertyinstead.enumProperty(String, Class, Function). UseconventionalEnumPropertyinstead.enumListProperty(String, Map). UseconventionalEnumListPropertyinstead.enumListProperty(String, Class, Function). UseconventionalEnumListPropertyinstead.
- java
AvoidBranchingStatementAsLastInLoopRule#CHECK_FOR. This constant should have never been public.AvoidBranchingStatementAsLastInLoopRule#CHECK_DO. This constant should have never been public.AvoidBranchingStatementAsLastInLoopRule#CHECK_WHILE. This constant should have never been public.AvoidBranchingStatementAsLastInLoopRule#CHECK_BREAK_LOOP_TYPES. This property descriptor should have been private. It won't be used anymore. UsegetPropertyDescriptoron the rule to retrieve the property descriptor.AvoidBranchingStatementAsLastInLoopRule#CHECK_CONTINUE_LOOP_TYPES. This property descriptor should have been private. It won't be used anymore. UsegetPropertyDescriptoron the rule to retrieve the property descriptor.AvoidBranchingStatementAsLastInLoopRule#CHECK_RETURN_LOOP_TYPES. This property descriptor should have been private. It won't be used anymore. UsegetPropertyDescriptoron the rule to retrieve the property descriptor.AvoidBranchingStatementAsLastInLoopRule#check. This method should have been private and will be internalized.AvoidBranchingStatementAsLastInLoopRule#hasPropertyValue. This method should have been private and will be internalized.AvoidBranchingStatementAsLastInLoopRule#checksNothing. This method should have been private and will be internalized.ClassFanOutOption#valueName,CycloOption#valueName,NcssOption#valueName- lang-test
AbstractMetricTestRule#optionMappings. No extra mapping is required anymore. TheMetricOptionenum values are used. SeeAbstractMetricTestRule(Metric, Class)to provide the enum at construction time.
✨️ Merged pull requests
- #6231: [java] New Rule: PublicMemberInNonPublicType - Andreas Dangel (@adangel)
- #6232: [java] New Rule: UnsupportedJdkApiUsage - Thomas Leplus (@thomasleplus)
- #6233: [core] Fix #6184: More consistent enum properties - Andreas Dangel (@adangel)
- #6290: [cli] Improve Designer start script - Andreas Dangel (@adangel)
- #6315: [java] Fix #5882: UnconditionalIfStatement false-negative if true/false is not literal - Marcel (@mrclmh)
- #6362: chore: Fix typos - Zbynek Konecny (@zbynek)
- #6366: [java] Fix #3857: InsufficientStringBufferDeclaration should consider constant Strings - Lukas Gräf (@lukasgraef)
- #6373: [java] Support Java 26 - Andreas Dangel (@adangel)
- #6377: [doc] chore: update last_updated - Andreas Dangel (@adangel)
- #6384: chore: helper script check-all-contributors.sh - Andreas Dangel (@adangel)
- #6386: [core] chore: Bump minimum Java version required for building to 21 - Andreas Dangel (@adangel)
- #6387: [ci] publish-pull-requests: download latest build result - Andreas Dangel (@adangel)
- #6389: chore: update javadoc deprecated tags - Andreas Dangel (@adangel)
- #6390: chore: update javadoc experimental tags - Andreas Dangel (@adangel)
- #6391: chore: update javadoc internal API tags - Andreas Dangel (@adangel)
- #6392: [doc] ADR 3: Clarify javadoc tags - Andreas Dangel (@adangel)
- #6394: [apex] Fix #6349: FieldDeclarationsShouldBeAtStart false positive with properties - Mohamed Hamed (@mdhamed238)
- #6407: [java] Fix #3601: InvalidLogMessageFormat: False positive when final parameter is Supplier<Throwable> - Lukas Gräf (@lukasgraef)
- #6417: [apex] Support CPD suppression with "CPD-OFF" & "CPD-ON" - Jade (@goto-dev-null)
- #6428: [ci] chore: run extensive integration tests under linux only - Andreas Dangel (@adangel)
- #6429: [doc] chore: add keywords for auxclasspath in Java documentation - Andreas Dangel (@adangel)
- #6430: [java] Fix #6364: Parse error with yield lambda - Andreas Dangel (@adangel)
📦️ Dependency updates
- #6367: Bump PMD from 7.19.0 to 7.20.0
- #6369: chore(deps): bump ruby/setup-ruby from 1.275.0 to 1.277.0
- #6370: chore(deps): bump org.apache.groovy:groovy from 5.0.2 to 5.0.3
- #6371: chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.18.2 to 1.18.3
- #6372: chore(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.6.2 to 3.6.3
- #6375: chore: Bump maven from 3.9.11 to 3.9.12
- #6378: chore(deps): bump ruby/setup-ruby from 1.277.0 to 1.279.0
- #6379: chore(deps): bump scalameta.version from 4.14.2 to 4.14.4
- #6380: chore(deps): bump junit.version from 6.0.1 to 6.0.2
- #6381: chore(deps): bump org.jsoup:jsoup from 1.21.2 to 1.22.1
- #6382: chore(deps): bump org.checkerframework:checker-qual from 3.52.1 to 3.53.0
- #6383: chore(deps): bump com.puppycrawl.tools:checkstyle from 12.3.0 to 13.0.0
- #6385: chore(deps): bump uri from 1.0.3 to 1.0.4 in /docs
- #6399: chore(deps): bump ruby/setup-ruby from 1.279.0 to 1.282.0
- #6400: chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.25.1 to 0.25.4
- #6401: chore(deps): bump org.sonatype.central:central-publishing-maven-plugin from 0.9.0 to 0.10.0
- #6403: chore(deps): bump com.google.protobuf:protobuf-java from 4.33.2 to 4.33.4
- #6410: chore(deps): bump ruby/setup-ruby from 1.282.0 to 1.285.0
- #6411: chore(deps): bump actions/cache from 5.0.1 to 5.0.2
- #6412: chore(deps): bump scalameta.version from 4.14.4 to 4.14.5
- #6413: chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.18.3 to 1.18.4
- #6414: chore(deps-dev): bump org.codehaus.mojo:versions-maven-plugin from 2.20.1 to 2.21.0
- #6415: chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.3 to 1.18.4
- #6419: chore(deps-dev): bump lodash from 4.17.21 to 4.17.23
- #6421: chore(deps): bump actions/setup-java from 5.1.0 to 5.2.0
- #6422: chore(deps): bump actions/checkout from 6.0.1 to 6.0.2
- #6423: chore(deps): bump scalameta.version from 4.14.5 to 4.14.6
- #6424: chore(deps-dev): bump org.assertj:assertj-core from 3.27.6 to 3.27.7
- #6425: chore(deps): bump org.apache.groovy:groovy from 5.0.3 to 5.0.4
📈️ Stats
- 146 commits
- 30 closed tickets & PRs
- Days since last release: 30