Skip to content

Releases: pmd/pmd

PMD 7.29.0-SNAPSHOT (07-October-2026)

Pre-release

Choose a tag to compare

@pmd-actions-helper pmd-actions-helper released this 25 Sep 09:32
8093782

30-October-2026 - 7.29.0-SNAPSHOT

The PMD team is pleased to announce PMD 7.29.0-SNAPSHOT.

This is a minor release.

Table Of Contents

🚀️ New and noteworthy

🌟️ New and Changed Rules

Changed Rules

  • The Java rule FinalFieldCouldBeStatic no longer reports casts or conditional expressions
    whose constant classification previously depended on a boxed static final field. Direct static field references
    are still reported.
  • The Java rule UnconditionalIfStatement now excludes final local boolean constants,
    consistently with its existing exclusion of named compile-time constants used for conditional compilation.
  • The Java rule UnusedNullCheckInEquals now recognizes final local String constants
    and unqualified instance String constants as non-null receivers, avoiding unnecessary reports.
  • The Java rule AvoidReassigningLoopVariables, with forReassign=skip, now accepts
    a final local constant equal to one as the increment of a conditional skip.
  • The Java rule UnusedAssignment now recognizes final local boolean constants
    when analyzing short-circuit conditions, avoiding false positives caused by assignments that cannot execute.
  • The Java rule LiteralsFirstInComparisons now recognizes final local String constants
    and unqualified references to non-static final String constants. This may add violations when such a constant
    is the argument of a comparison, or remove them when it is already the receiver.
  • The Java rule UseExplicitTypes has a new property allowLongTypeNames. It allows
    to use var when the explicit type name would be longer than a given minimum length configured with
    this property.

🐛️ Fixed Issues

  • core
    • #6912: [core] Include XML validation details in ruleset loading errors
    • #7156: [core] Analysis cache fails with ZipException on invalid archive on the auxclasspath
  • groovy
    • #7110: [groovy] Fix #7100: CPD fails on GStrings ending in an interpolated variable
  • java
    • #7060: [java] getConstValue() returns null for constant expressions referencing final local variables
    • #7133: [java] CPD: Constructor detection state leaks between files with --ignore-identifiers
    • #7145: [java] Lambda with a parenthesized expression body is treated as void-compatible
  • java-bestpractices
    • #5159: [java] UnusedAssignment false positive when using assert
  • java-codestyle
    • #6903: [java] Enhance UseExplicitTypes to allow verbose long explicit types
  • java-design
    • #4815: [java] ExceptionAsFlowControl false-positive on Lambda/asynchronous (7.0.0-rc4)
    • #7117: [java] ExceptionAsFlowControl: false negative when the lambda is invoked by the method it is passed to

🚨️ API Changes

  • Java constant folding now recognizes final primitive and String variables initialized with constant expressions,
    including local variables and unqualified instance fields. Numeric references are converted to their declared type.
    Boxed fields and field accesses qualified by expressions (such as this.CONSTANT) are not compile-time constants.
    These changes affect ASTExpression.getConstValue(), isCompileTimeConstant(), and the XPath attribute
    @CompileTimeConstant; custom Java and XPath rules relying on them may report different results.

✨️ Merged pull requests

📦️ Dependency updates

📈️ Stats

PMD 7.28.0 (25-September-2026)

Choose a tag to compare

@pmd-actions-helper pmd-actions-helper released this 25 Sep 09:00
pmd_releases/7.28.0
79726f0

25-September-2026 - 7.28.0

The PMD team is pleased to announce PMD 7.28.0.

This is a minor release.

Table Of Contents

🚀️ New and noteworthy

Kotlin XPath functions and type attributes

Type data is now accessible in XPath rules via new attributes and helper functions (see Kotlin XPath rule support):

  • Type-info Attributes: @TypeName, @ReturnTypeName, @AnnotationFqNames
    are exposed on declaration nodes (property, function, class, parameter, catch, for-loop, delegation specifier,
    annotation nodes). These attributes depend on type resolution: they are only available when auxClasspath
    is configured and the kotlin-type-mapper analysis has resolved the types.
  • General Attributes: @Mutable, @Identifier, @Name
    are exposed on declaration and import related nodes. These attributes don't depend on type resolution, so
    they're always present regardless of auxClasspath.
  • XPath functions:
    • pmd-kotlin:typeIs(typeName): matches if the node's type is typeName or a subtype.
    • pmd-kotlin:typeIsExactly(typeName): matches the exact declared type only (no subtypes).
    • pmd-kotlin:hasAnnotation(name): matches if the node has an annotation with the given simple or FQN.
    • pmd-kotlin:modifiers(): returns the modifier keywords of a declaration as a sequence.
    • pmd-kotlin:isNullable(): returns true if the node's declared type is nullable (has ?).
    • pmd-kotlin:hasUnresolvedReference(): returns true if the node contains an unresolved reference.
    • pmd-kotlin:matchesSig(signature): matches call sites by method signature pattern (supports wildcards).

🌟️ New and Changed Rules

New Rules

  • The new Java rule OnDemandImport reports on-demand imports, also known as wildcard imports.
    By default, static imports from JUnit and TestNG are allowed. The allowed static and type import packages
    can be configured with allowStaticImportsFrom and allowTypeImportsFrom.
  • The new Java rule LongLiteralEndingWithLowercaseL finds long literals ending with a lowercase l.
    That helps to avoid confusion between numbers ending with 1 and l. Uppercase L should be used to define long literals.
  • The new Java rule TypeNameMismatch finds types that are not defined in a .java file
    with the same name. Enforcing a match between source file name and type name makes it easier to
    find source code for given type.
  • The new Java rule CStyleArrayDeclaration finds C-style declarations of arrays (e.g. int numbers[]).
    That helps you use Java-style declarations (e.g. int[] numbers) consistently throughout the codebase.
  • The new Java rule InternalApiUsage reports usages of internal or test-only APIs
    (e.g. annotated with @VisibleForTesting, @TestOnly, @API(status=INTERNAL) or @ApiStatus.Internal)
    from code that shouldn't depend on them.
  • The new Apex rule ApexUnitTestClassShouldHaveRunRelevantTestsAnnotation finds unit tests
    that do not use the new @IsTest(critical=true) or @IsTest(testFor='...') annotation parameters for tests.
    These parameters help to identify which tests should be executed during a RunRelevantTests deployment.
    Note: These annotation parameters are Beta and require Salesforce API 66.0+.

Changed Rules

  • The property checkNonStaticMethods of the rule NonThreadSafeSingleton is now
    deprecated and no longer has any effect. Its implementation did the opposite of what the documentation described.
    The rule now always reports both static and non-static methods; previously it reported only static methods
    by default.
    This may result in additional violations being reported.
    If you want to suppress violations for non-static methods, you can use
    suppression via XPath, e.g.
    <property name="violationSuppressXPath" value=".[ancestor-or-self::MethodDeclaration[1][@Static = false()]]" />
  • The property statementOrderMatters of the rule VariableCanBeInlined is now deprecated.
    Setting it to false relaxes the rule under the unsafe assumption that intervening statements have no side
    effects, which can lead to false positives. The property will be removed in PMD 8.0.0.

🐛️ Fixed Issues

  • apex-bestpractices
    • #6988: [apex] New rule: Detect usage of @IsTest(critical=true) / @IsTest(testFor='...') annotations (RunRelevantTests, Beta, API 66.0+)
  • core
    • #7013: [core] PMDConfiguration - "Can't mix setClasspath with getAuxClasspath!"
  • cli
    • #7090: [cli] Add the missing exit code 5 to the CLI help
  • html
    • #6135: [html] HtmlCpdLexer giving IndexOutOfBoundsException when script contains unescaped closing tag
  • java
    • #6926: [java] IllegalArgumentException (Mismatched list sizes) with inconsistent unresolved generic arity
    • #7056: [java] Provide ability to disable auxClasspath warning added in 7.27.0
    • #7081: [java] NoSuchFileException when auxClasspath is given as a classpath file (file: URL) (since 7.27.0)
    • #7101: [java] ZipException when auxClasspath contains a non-jar file (since 7.27.0)
  • java-bestpractices
    • #5940: [java] UnusedAssignment: False positive when assignment is in conditional statement
    • #6901: [java] MethodReturnsInternalArray: Various false negatives with local aliases and conditional expressions
    • #7033: [java] New rule: TypeNameMismatch
    • #7047: [java] New rule: OnDemandImport
  • java-codestyle
    • #3124: [java] UnnecessaryLocalBeforeReturn/VariableCanBeInlined: deprecate property statementOrderMatters
    • #5732: [java] UnnecessaryCast false positive with package private methods
    • #7026: [java] New rule: CStyleArrayDeclaration
  • java-design
    • #6513: [java] SimplifyConditional: False negative when null check and instanceof are separated by other && conditions
    • #6694: [java] SimplifyBooleanReturns triggers inconsistently depending on redundant parentheses in return expression
    • #6889: [java] New rule: InternalApiUsage
  • java-documentation
    • #6450: [java] DanglingJavadoc: False positive on /// comments for Java < 23
  • java-errorprone
    • #1050: [java] NullAssignment: False positive inside if statement for first assignment
    • #6693: [java] CloneMethodMustImplementCloneable: False positive with throw-via-local
    • #7009: [java] ReplaceJavaUtilDate: False negative when using pattern matching
    • #7027: [java] New rule: LongLiteralEndingWithLowercaseL
    • #7068: [java] UnusedReturnValue: False positive for calls made on Mockito.verify(mock)
  • java-multithreading
    • #6297: [java] AvoidUsingVolatile: Update documentation
    • #6780: [java] NonThreadSafeSingleton: False negative with property checkNonStaticMethods
  • java-security
    • #7007: [java] HardCodedCryptoKey: False negative when a hard-coded key is constructed via new String(char[])
    • #7008: [java] HardCodedCryptoKey: False positive when the key comes from System.getProperty()
  • kotlin
    • #6893: [kotlin] Add XPath functions and type attributes
  • miscellaneous
    • #6961: [doc] When a rule's description has a link to another rule in the exact wrong position, the do...
Read more

PMD 7.27.0 (28-August-2026)

Choose a tag to compare

@pmd-actions-helper pmd-actions-helper released this 28 Aug 12:41
pmd_releases/7.27.0
360072e

28-August-2026 - 7.27.0

The PMD team is pleased to announce PMD 7.27.0.

This is a minor release.

Table Of Contents

🚀️ New and noteworthy

Java 27 Support

This release of PMD brings support for Java 27.

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 27-preview:

pmd check --use-version java-27-preview ...

Note: Support for Java 25 preview language features have been removed. The version "25-preview"
is no longer available.

Updated Apex Support

The Apex language support has been bumped to version 67.0 (Summer '26). It supports the new
Multiline String literals.

Kotlin type-aware analysis

Kotlin now supports type-aware analysis via the auxClasspath language property (see #6677).
Resolved type names, return types, and annotation FQNs are available through
KotlinNodeTypeData for use in Java-based rules.

Note: Type data is not yet accessible in XPath rules or the PMD Rule Designer. This will be added in the next version.

🌟️ New and Changed Rules

New Rules

  • The new java rule UnusedReturnValue (Java Error Prone) finds method calls whose result is not used,
    although ignoring the result of these method calls is likely a mistake.
    The rule is referenced in the quickstart.xml ruleset for Java.
  • New rule ProtectedMemberInFinalClass (Java Design) finds protected members defined in final classes.
    Such members should use package or private visibility to clarify their intended scope.
    The rule replaces now deprecated rules AvoidProtectedFieldInFinalClass and AvoidProtectedMethodInFinalClassNotExtending
    and flags members that were previously not detected by either of these rules, such as nested types or constructors.
    The rule is referenced in the quickstart.xml ruleset for Java.

Renamed Rules

  • The rule InstantiableUtilityClass (Java Design) was renamed from UseUtilityClass to better reflect the problem.
    The old name still works but is deprecated.

Changed Rules

  • The rule CommentRequired (Java Documentation)
    has a new property packageMethodCommentRequirement. It controls whether Javadoc comments are required (or
    unwanted) for package-private methods and constructors. Previously, only public and protected methods could
    be configured (via publicMethodCommentRequirement and protectedMethodCommentRequirement). The new property
    defaults to Ignored, so existing rule configurations are unaffected.
    This was implemented in #6880.
  • The rule BooleanGetMethodName (Java Codestyle) has a new property
    includeWrappedType. If set to true (default), the rule treats Boolean and boolean identical.
    If set to false, the rule follows the bean convention and treats Boolean like any other object.

Deprecated Rules

🐛️ Fixed Issues

  • apex
    • #6478: [apex] Parser error when using CALENDAR_YEAR() in SOQL
    • #6887: [apex] ParseException on Summer '26 multiline string literals ('''...''')
  • apex-bestpractices
    • #5904: [apex] ApexUnitTestShouldNotUseSeeAllDataTrue violation range should only be the annotation and not the entire test method
  • java
    • #5041: [java] Parsing failed in ParseLock#doParse(): IndexOutOfBoundsException
    • #6010: [java] java.lang.OutOfMemoryError: Java heap space when accessing big Jar files with PMD 7
    • #6374: [java] Support Java 27
    • #6768: [java] Disambiguation IllegalStateException resolving a synthesized record accessor used as a call argument alongside an anonymous class
    • #6932: [java] AssertionError when outer class is parsed before inner class with conflicting visibility
  • java-bestpractices
    • #1237: [java] AbstractClassWithoutAnyMethod: False positive for empty subclasses that inherit methods
    • #1287: [java] GuardLogStatement: False positive when using negative guard conditions
    • #2033: [jsp] NoClassAttribute: False positive for jsp:useBean
    • #5514: [java] ExhaustiveSwitchHasDefault: False positive for non-exhaustive switch statements
    • #5670: [java] ExhaustiveSwitchHasDefault: False positive with final fields not initialized in constructor
    • #6200: [java] UnusedAssignment: False positive about the ++ unary operator
    • #6393: [java] UnusedPrivateMethod: False positive with overloaded private methods called with values returned from methods of an unresolved type
    • #6611: [java] UnnecessaryVarargsArrayCreation: False positive when removing the array creates overload ambiguity
    • #6965: [java] AbstractClassWithoutAnyMethod: False Positive on derived abstract class
  • java-codestyle
    • #2974: [java] Merge rules about protected in final class (AvoidProtectedFieldInFinalClass, AvoidProtectedMethodInFinalClassNotExtending)
    • #5441: [java] UseDiamondOperator: False positive with interdependent generic vars
    • #6958: [java] BooleanGetMethodName should have the option to treat boolean wrapper type differently
    • #6274: [java] UselessParentheses: False positive in ternary else expression
    • #6651: [java] UnnecessaryImport: False positive when Javadoc {@link} references an array type
    • #6709: [java] LambdaCanBeMethodReference: False positive with array creation containing constructor call in receiver
    • #6737: [java] TooManyStaticImports: @SuppressWarnings("PMD.TooManyStaticImports") has stopped working
    • #6846: [java] VariableDeclarationUsageDistance: False positive with variables grouped at the top of a block
    • #6867: [java] UnnecessaryFullyQualifiedName: ContextedAssertionError: This should be unreachable: unknown constant ScopeInfo: MODULE_IMPORT
    • #6943: [java] UnnecessaryCast: False positives related to generics
  • java-design
    • #6714: [java] Rename UseUtilityClass to InstantiableUtilityClass
    • #6844: [java] AvoidThrowingNewInstanceOfSameException: message inconsistent with logic
    • #6881: [java] CognitiveComplexity does not count switch expressions
    • #6925: [java] ImmutableField: False positive on picocli annotated fields
  • java-documentation
Read more

PMD 7.26.0 (29-June-2026)

Choose a tag to compare

@pmd-actions-helper pmd-actions-helper released this 29 Jun 09:27
pmd_releases/7.26.0
8fd38ed

29-June-2026 - 7.26.0

The PMD team is pleased to announce PMD 7.26.0.

This is a minor release.

Table Of Contents

🚀️ New and noteworthy

Swift Changes

The Swift parser now forwards syntax errors as usual processing errors. Before it just logged any errors and
tried to move on, resulting in an incomplete AST with error nodes. As part of this change, the grammar has been
slightly improved around macro declarations, generic parameters and parameter packs.
This means that PMD might fail now on Swift files with processing errors, when it previously ran without
obvious problems. The Swift module in PMD now behaves like other modules in regard to error handling.

Updated PMD Designer

This PMD release ships a new version of the pmd-designer.
For the changes, see PMD Designer Changelog (7.19.3).

🌟️ New and Changed Rules

New Rules

  • The new Java rule WrongTestAnnotation detects when test annotations from the wrong
    testing framework (JUnit 4, JUnit Jupiter, or TestNG) are used in your code, preventing tests from being silently
    skipped due to framework mismatches. This helps avoid the silent failure where tests compile but don't execute
    because the test runner doesn't recognize the annotation.
  • The new Java rule AssertEqualsArgumentOrder detects assertions
    where the expected and actual arguments were swapped. This helps find assertions
    that are producing a confusing error message when they fail.
  • The new Kotlin rule LocalVariableShadowsParameter detects local variable
    declarations that use the same name as a parameter of the enclosing function. This shadows the parameter
    and may lead to confusion about which value is used.
  • The new Apex rule InvocableClassNoArgConstructor detects classes that use
    @InvocableVariable properties, but that don't provide a no-arg constructor. Without such a constructor,
    runtime exception occur when Salesforce Flow tries to instantiate such classes.

Deprecated Rules

🐛️ Fixed Issues

  • apex
    • #6806: [apex] ANTLR runtime mismatch 4.9.1 used for code generation does not match the current runtime version 4.13.2
  • apex-errorprone
    • #6793: [apex] New Rule: Invocable Classes require a no argument constructor
  • apex-security
    • #2955: [apex] ApexSOQLInjection: False positive when passing local var with concatenating strings
    • #3877: [apex] ApexCRUDViolation: False positive with Lists of Objects with getSObjectType().getDescribe()
  • core
    • #6764: [core] ANTLR: Report syntax errors as processing errors
  • cpp
    • #6641: [cpp]: IndexOutOfBoundsException in CPD when a duplication is at end of file with UTF8-BOM
  • cli
    • #6741: [cli] Designer: Fix quotes in PMD_OPENJFX_MODULE_PATH setting
  • java
    • #6812: [java] Rename ASTMethodDeclaration#isOverridden() to isOverride()
  • java-bestpractices
    • #6627: [java] UnusedPrivateMethod: could not handle javax.annotation
    • #6692: [java] ForLoopCanBeForeach: inconsistent detection between i += 1 and i = i + 1 update forms
    • #6736: [java] JUnitJupiterTestShouldBePackagePrivate: False negative when the only tests are in a @Nested class
    • #6782: [java] UseStandardCharsets: ArrayIndexOutOfBoundsException in line 81
  • java-codestyle
    • #6239: [java] UseDiamondOperator: False positive with Guice TypeLiteral
    • #6775: [java] UselessParentheses: False negative when on the right-hand side of an assignment statement
  • java-design
    • #3741: [java] Deprecate UseObjectForClearerAPI
    • #6459: [java] PublicMemberInNonPublicType: False positive for main(...) methods
    • #6460: [java] PublicMemberInNonPublicType: False negative for overridden methods
    • #6814: [java] AvoidDeepNestedIfStmts: count ifs properly in else branch
  • java-errorprone
    • #2846: [java] New Rule: WrongTestAnnotation
    • #5011: [java] TestClassWithoutTestCases: False positive for test classes extending a class with tests (in nested classes)
    • #6743: [java] CloseResource: False positive for closeable initialized with (T) null
    • #6781: [java] UselessPureMethodCall: False positive for Stream.forEach
  • java-performance
    • #6740: [java] OptimizableToArrayCall: False positive when new T[0x0] is used instead of new T[0]
  • kotlin
    • #6677: [kotlin] Add auxClasspath language property
  • kotlin-bestpractices
    • #6732: [kotlin] New Rule: LocalVariableShadowsParameter
  • swift
    • #6801: [swift] Report syntax errors as processing errors

🚨️ API Changes

✨️ Merged pull requests

Read more

PMD 7.25.0 (29-May-2026)

Choose a tag to compare

@pmd-actions-helper pmd-actions-helper released this 29 May 07:31
pmd_releases/7.25.0
418f8b7

29-May-2026 - 7.25.0

The PMD team is pleased to announce PMD 7.25.0.

This is a minor release.

Table Of Contents

🚀️ New and noteworthy

Updated ANTLR library to 4.13.2

We have updated the ANTLR library (parser generator) from 4.9.3 to the latest version 4.13.2,
in order to be able to use the latest version of Apex parser library.

This is an incompatible update: In case you use custom language modules based on ANTLR, you
need to make sure to regenerate all of your lexers and parsers with the new ANTLR version.

For the ANTLR based language modules, that PMD ships (kotlin and swift and various CPD modules),
this is already done.

🌟️ New and Changed Rules

New Rules

  • The new Java rule JUnitJupiterTestNoPrivateModifier find JUnit test classes and
    methods that are private. Test classes, test methods, and lifecycle methods are not required to be public,
    but they must not be private. Otherwise, they won’t be found by the test framework.
  • The new Java rule UnnecessaryBlock reports blocks that are unnecessary as
    they don't introduce a new scope. This rule helps simplify code structure by identifying and flagging
    redundant blocks that can make code harder to read and may be misleading.
  • The new Java rule VariableDeclarationUsageDistance flags local variables that are declared
    far from their usage, which can make code harder to read. The rule has a property maxDistance that allows to
    configure the maximum allowed distance between declaration and usage.
  • The new Java rule AssertStatementInTest detects usages of assert statement in tests.
    These should be replaced by framework assertion methods such as assertEquals.
    Such methods provide better error messages and make test behave correctly when running without -ea.

Changed Rules

Renamed rules and properties

Read more

PMD 7.24.0 (24-April-2026)

Choose a tag to compare

@pmd-actions-helper pmd-actions-helper released this 24 Apr 10:32
pmd_releases/7.24.0
e9787d8

24-April-2026 - 7.24.0

The PMD team is pleased to announce PMD 7.24.0.

This is a minor release.

Table Of Contents

🌟️ New Rules

  • The new Apex rule AvoidInterfaceAsMapKey reports Map declarations
    (fields, variables, parameters) whose key type is an interface that has at least one abstract implementing
    class defining equals or hashCode. Using such maps results in potentially duplicated map entries or
    not being able to get entries by key.
  • The new Java rule OverridingThreadRun finds overridden Thread::run methods.
    This is not recommended. Instead, implement Runnable and pass an instance to the thread constructor.

🐛️ Fixed Issues

  • apex
    • #5386: [apex] Apex files ending in "Test" are skipped with a number of rules
  • apex-errorprone
    • #6492: [apex] New rule: Prevent use of interface -> abstract class with equals/hashCode as key in Map
  • apex-security
    • #5385: [apex] ApexCRUDViolation not reported even if SOQL doesn't have permissions check on it
  • java-bestpractices
    • #4272: [java] JUnitTestsShouldIncludeAssert: False positive with assert in lambda
  • java-multithreading
    • #595: [java] New rule: Implement Runnable instead of extending Thread
  • kotlin
    • #6003: [kotlin] Support multidollar interpolation (Kotlin 2.2)

✨️ Merged pull requests

📦️ Dependency updates

  • #6515: chore: bump pmd-regression-tester from 1.6.2 to 1.7.0
  • #6552: Bump PMD from 7.22.0 to 7.23.0
  • #6564: chore(deps): bump ruby/setup-ruby from 1.295.0 to 1.299.0
  • #6565: chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.18.7 to 1.18.8
  • #6566: chore(deps): bump com.puppycrawl.tools:checkstyle from 13.3.0 to 13.4.0
  • #6567: chore(deps-dev): bump log4j.version from 2.25.3 to 2.25.4
  • #6569: chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.7 to 1.18.8
  • #6570: chore(deps): bump org.apache.groovy:groovy from 5.0.4 to 5.0.5
  • #6571: chore(deps-dev): bump io.github.git-commit-id:git-commit-id-maven-plugin from 9.0.2 to 9.1.0
  • #6572: chore(deps): bump bigdecimal from 4.0.1 to 4.1.0 in /docs
  • #6578: chore(deps): bump marocchino/sticky-pull-request-comment from 3.0.2 to 3.0.3
  • #6579: chore(deps): bump crate-ci/typos from 1.44.0 to 1.45.0
  • #6580: chore(deps): bump ruby/setup-ruby from 1.299.0 to 1.300.0
  • #6581: chore(deps-dev): bump io.github.git-commit-id:git-commit-id-maven-plugin from 9.1.0 to 10.0.0
  • #6582: chore(deps): bump org.checkerframework:checker-qual from 3.54.0 to 4.0.0
  • #6583: chore(deps-dev): bump ant.version from 1.10.15 to 1.10.16
  • #6584: chore(deps): bump bigdecimal from 4.1.0 to 4.1.1 in /docs
  • #6588: chore(deps): bump actions/cache from 5.0.4 to 5.0.5
  • #6589: chore(deps): bump marocchino/sticky-pull-request-comment from 3.0.3 to 3.0.4
  • #6590: chore(deps): bump crate-ci/typos from 1.45.0 to 1.45.1
  • #6591: chore(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1
  • #6592: chore(deps): bump actions/create-github-app-token from 3.0.0 to 3.1.1
  • #6593: chore(deps): bump scalameta.version from 4.15.2 to 4.16.0
  • #6594: chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.25.4 to 0.25.5
  • #6595: chore(deps-dev): bump com.google.guava:guava from 33.5.0-jre to 33.6.0-jre
  • #6596: chore(deps-dev): bump ant.version from 1.10.16 to 1.10.17
  • #6599: chore(deps-dev): Bump lodash from 4.17.23 to 4.18.1
  • #6600: chore(deps-dev): Bump addressable from 2.8.9 to 2.9.0
  • #6613: chore(deps): bump ruby/setup-ruby from 1.300.0 to 1.305.0
  • #6614: chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.25.5 to 0.25.6
  • #6615: chore(deps): bump scalameta.version from 4.16.0 to 4.16.1
  • #6616: chore(deps-dev): bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.5.0.6356 to 5.6.0.6792
  • #6617: chore(deps): bump org.jsoup:jsoup from 1.22.1 to 1.22.2
  • #6618: chore(deps): bump bigdecimal from 4.1.1 to 4.1.2 in /docs

📈️ Stats

  • 82 commits
  • 14 closed tickets & PRs
  • Days since last release: 27

PMD 7.23.0 (27-March-2026)

Choose a tag to compare

@pmd-actions-helper pmd-actions-helper released this 27 Mar 11:16
pmd_releases/7.23.0
8562692

27-March-2026 - 7.23.0

The PMD team is pleased to announce PMD 7.23.0.

This is a minor release.

Table Of Contents

🐛️ Fixed Issues

  • core
    • #6503: [core] Links in HTML report are broken
  • java-errorprone
    • #6502: [java] CloseResource: False positive for allowedResourceMethodPatterns entries when using unqualified method calls
  • java-security
    • #6531: [java] InsecureCryptoIv: False negative with fixed IVs from array initializers

✨️ Merged pull requests

📦️ Dependency updates

  • #6476: Bump PMD from 7.21.0 to 7.22.0
  • #6479: chore(deps): bump actions/download-artifact from 7.0.0 to 8.0.0
  • #6480: chore(deps): bump actions/upload-artifact from 6.0.0 to 7.0.0
  • #6481: chore(deps): bump com.puppycrawl.tools:checkstyle from 13.2.0 to 13.3.0
  • #6482: chore(deps): bump org.mockito:mockito-core from 5.21.0 to 5.22.0
  • #6483: chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.18.5 to 1.18.7
  • #6484: chore(deps): bump org.yaml:snakeyaml from 2.5 to 2.6
  • #6485: chore(deps): bump org.checkerframework:checker-qual from 3.53.1 to 3.54.0
  • #6486: chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.5 to 1.18.7
  • #6487: chore(deps): bump com.google.protobuf:protobuf-java from 4.33.5 to 4.34.0
  • #6490: chore: Update gems, remove github-pages
  • #6498: chore(deps): bump ruby/setup-ruby from 1.288.0 to 1.290.0
  • #6499: chore(deps-dev): bump commons-logging:commons-logging from 1.3.5 to 1.3.6
  • #6500: chore(deps-dev): bump org.apache.maven.plugins:maven-shade-plugin from 3.6.1 to 3.6.2
  • #6501: chore(deps): bump org.apache.maven.plugins:maven-resources-plugin from 3.4.0 to 3.5.0
  • #6506: chore(deps): bump actions/create-github-app-token from 2.2.1 to 3.0.0
  • #6507: chore(deps): bump actions/download-artifact from 8.0.0 to 8.0.1
  • #6508: chore(deps): bump marocchino/sticky-pull-request-comment from 2.9.4 to 3.0.2
  • #6509: chore(deps): bump ruby/setup-ruby from 1.290.0 to 1.295.0
  • #6511: chore(deps): bump org.mockito:mockito-core from 5.22.0 to 5.23.0
  • #6514: chore: bump maven from 3.9.12 to 3.9.14
  • #6516: chore: bump json from 2.19.0 to 2.19.2
  • #6548: chore(deps): bump actions/cache from 5.0.3 to 5.0.4
  • #6549: chore(deps): bump com.google.protobuf:protobuf-java from 4.34.0 to 4.34.1
  • #6551: chore: use ruby4

📈️ Stats

  • 38 commits
  • 9 closed tickets & PRs
  • Days since last release: 27

PMD 7.22.0 (27-February-2026)

Choose a tag to compare

@pmd-actions-helper pmd-actions-helper released this 27 Feb 12:03
pmd_releases/7.22.0
7f74d77

27-February-2026 - 7.22.0

The PMD team is pleased to announce PMD 7.22.0.

This is a minor release.

Table Of Contents

🚀️ New and noteworthy

Security fixes

  • This release fixes a stored XSS vulnerability in VBHTMLRenderer and YAHTMLRenderer via unescaped violation messages.
    Affects CI/CD pipelines that run PMD with --format vbhtml or --format yahtml on untrusted source code
    (e.g. pull requests from external contributors) and expose the HTML report as a build artifact.
    JavaScript executes in the browser context of anyone who opens the report.
    Note: The default html format is not affected by unescaped violation messages, but a similar problem
    existed with suppressed violation markers.
    If you use these reports, it is recommended to upgrade PMD.
    Reported by Smaran Chand (@smaranchand).

🌟️ New and Changed Rules

New Rules

  • The new Java rule UnnecessaryInterfaceDeclaration detects classes that
    implement interfaces that are already implemented by its superclass, and interfaces
    that extend other interfaces already declared by their superinterfaces.
    These declarations are redundant and can be removed to simplify the code.

Changed Rules

  • The rule CloseResource introduces a new property, allowedResourceMethodPatterns,
    which lets you specify method invocation patterns whose return values are resources managed externally.
    This is useful for ignoring managed resources - for example, Reader/Writer instances obtained from
    HttpServletRequest/HttpServletResponse - because the servlet container, not application code,
    is responsible for closing them. By default, the rule ignores InputStream/OutputStream/Reader/Writer
    resources returned by methods on (Http)ServletRequest and (Http)ServletResponse
    (both javax.servlet and jakarta.servlet).

🐛️ Fixed Issues

  • core
    • #6471: [core] BaseAntlrTerminalNode should return type instead of index for getTokenKind()
    • #6475: [core] Fix stored XSS in VBHTMLRenderer and YAHTMLRenderer
  • doc
    • #6396: [doc] Mention test-pmd-tool as alternative for testing
  • java-bestpractices
    • #6431: [java] UnitTestShouldIncludeAssert: False positive with SoftAssertionsExtension on parent/grandparent classes
  • java-codestyle
    • #6458: [java] New Rule: UnnecessaryInterfaceDeclaration
  • java-errorprone
    • #5787: [java] InvalidLogMessageFormat: False positive with lombok @Value generated methods
    • #6436: [java] CloseResource: Allow to ignore managed resources

🚨️ API Changes

Deprecations

✨️ Merged pull requests

📦️ Dependency updates

  • #6433: Bump PMD from 7.20.0 to 7.21.0
  • #6438: chore(deps): bump actions/cache from 5.0.2 to 5.0.3
  • #6439: chore(deps): bump ruby/setup-ruby from 1.286.0 to 1.288.0
  • #6440: chore(deps): bump scalameta.version from 4.14.6 to 4.14.7
  • #6441: chore(deps): bump org.apache.maven.plugins:maven-compiler-plugin from 3.14.1 to 3.15.0
  • #6442: chore(deps): bump org.checkerframework:checker-qual from 3.53.0 to 3.53.1
  • #6443: chore(deps): bump com.puppycrawl.tools:checkstyle from 13.0.0 to 13.1.0
  • #6444: chore(deps): bump com.google.protobuf:protobuf-java from 4.33.4 to 4.33.5
  • #6452: chore(deps): bump actions/checkout from 6.0.1 to 6.0.2
  • #6455: chore(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.9.0 to 3.10.0
  • #6456: chore(deps): bump com.puppycrawl.tools:checkstyle from 13.1.0 to 13.2.0
  • #6462: chore(deps): bump junit.version from 6.0.2 to 6.0.3
  • #6463: chore(deps): bump scalameta.version from 4.14.7 to 4.15.2
  • #6465: chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.4 to 1.18.5
  • #6468: chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.18.4 to 1.18.5
  • #6469: chore(deps): bump surefire.version from 3.5.4 to 3.5.5
  • #6470: chore(deps): bump org.jetbrains:annotations from 26.0.2-1 to 26.1.0
  • #6473: chore(deps): bump nokogiri to 1.19.1
  • #6474: chore(deps): bump faraday from 2.13.3 to 2.14.1

📈️ Stats

  • 66 commits
  • 16 closed tickets & PRs
  • Days since last release: 28

PMD 7.21.0 (30-January-2026)

Choose a tag to compare

@pmd-actions-helper pmd-actions-helper released this 30 Jan 09:52
pmd_releases/7.21.0
4558030

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: 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-OFF comment pairs. See #6417

🌟️ New and Changed Rules

New Rules

  • The new Java rule PublicMemberInNonPublicType detects 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 the public modifier can create confusion.
  • The new Java rule UnsupportedJdkApiUsage flags the use of unsupported and non-portable
    JDK APIs, including sun.* packages, sun.misc.Unsafe, and jdk.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 checkAddressTypes of rule AvoidUsingHardCodedIP has changed:
    • Instead of IPv4 use ipv4
    • Instead of IPv6 use ipv6
    • Instead of IPv4 mapped IPv6 use ipv4MappedIpv6
    • The old values still work, but you'll see a deprecation warning.
  • The property nullCheckBranch of rule ConfusingTernary has changed:
    • Instead of Any use any
    • Instead of Then use then
    • Instead of Else use else
    • The old values still work, but you'll see a deprecation warning.
  • The property typeAnnotations of rule ModifierOrder has changed:
    • Instead of ontype use onType
    • Instead of ondecl use onDecl
    • The old values still work, but you'll see a deprecation warning.
  • The values of the properties of rule CommentRequired have changed:
    • Instead of Required use required
    • Instead of Ignored use ignored
    • Instead of Unwanted use unwanted
    • The old values still work, but you'll see a deprecation warning.

Deprecated Rules

🐛️ 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

Read more

PMD 7.20.0 (30-December-2025)

Choose a tag to compare

@pmd-actions-helper pmd-actions-helper released this 30 Dec 15:44
pmd_releases/7.20.0
fa478ec

30-December-2025 - 7.20.0

The PMD team is pleased to announce PMD 7.20.0.

This is a minor release.

Table Of Contents

🌟️ Changed Rules

  • The Java rule OnlyOneReturn has a new property ignoredMethodNames. This property by
    default is set to compareTo and equals, thus this rule now by default allows multiple return statements
    for these methods. To restore the old behavior, simply set this property to an empty value.

🐛️ Fixed Issues

  • core
    • #6330: [core] "Unable to create ValueRepresentation" when using @LiteralText (XPath)
  • java
    • #6234: [java] Parser fails to parse switch expressions in super() constructor calls
    • #6299: [java] Fix grammar of switch label
  • java-bestpractices
    • #4282: [java] GuardLogStatement: False positive when guard is not a direct parent
    • #6028: [java] UnusedPrivateMethod: False positive with raw type for generic method
    • #6257: [java] UnusedLocalVariable: False positive with instanceof pattern guard
    • #6291: [java] EnumComparison: False positive for any object when object.equals(null)
    • #6328: [java] UnusedLocalVariable: False positive for pattern variable in for-each without braces
  • java-codestyle
    • #4257: [java] OnlyOneReturn: False positive with equals method
    • #5043: [java] LambdaCanBeMethodReference: False positive on overloaded methods
    • #6237: [java] UnnecessaryCast: ContextedRuntimeException when parsing switch expression with lambdas
    • #6279: [java] EmptyMethodInAbstractClassShouldBeAbstract: False positive for final empty methods
    • #6284: [java] UnnecessaryConstructor: False positive for JavaDoc-bearing constructor
  • java-errorprone
    • #6276: [java] NullAssignment: False positive when assigning null to a final field in a constructor
    • #6343: [java] MissingStaticMethodInNonInstantiatableClass: False negative when method in nested class returns null
  • java-performance
    • #4158: [java] BigIntegerInstantiation: False negative with compile-time constant
    • #4910: [java] ConsecutiveAppendsShouldReuse: False positive within if-statement without curly braces
    • #5877: [java] AvoidArrayLoops: False negative when break inside switch statement
  • maintenance
    • #6230: [core] Single module snapshot build fails

🚨️ API Changes

Experimental API

✨️ Merged pull requests

📦️ Dependency updates

  • #6286: Bump PMD from 7.18.0 to 7.19.0
  • #6300: chore(deps): bump actions/checkout from 6.0.0 to 6.0.1
  • #6301: chore(deps): bump org.checkerframework:checker-qual from 3.52.0 to 3.52.1
  • #6302: chore(deps): bump org.apache.maven.plugins:maven-resources-plugin from 3.3.1 to 3.4.0
  • #6303: chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.18.1 to 1.18.2
  • #6304: chore(deps): bump com.puppycrawl.tools:checkstyle from 12.1.2 to 12.2.0
  • #6305: chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.3.0.6276 to 5.4.0.6343
  • #6306: chore(deps): bump webrick from 1.9.1 to 1.9.2 in /docs
  • #6318: chore(deps): bump actions/create-github-app-token from 2.2.0 to 2.2.1
  • #6319: chore(deps): bump actions/setup-java from 5.0.0 to 5.1.0
  • #6320: chore(deps): bump ruby/setup-ruby from 1.268.0 to 1.269.0
  • #6321: chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.1 to 1.18.2
  • #6323: chore(deps): bump com.google.protobuf:protobuf-java from 4.33.1 to 4.33.2
  • #6324: chore(deps): bump io.github.apex-dev-tools:apex-ls_2.13 from 6.0.1 to 6.0.2
  • #6325: chore(deps): bump org.apache.maven.plugins:maven-assembly-plugin from 3.7.1 to 3.8.0
  • #6329: chore(deps): bump org.mozilla:rhino from 1.7.15 to 1.7.15.1
  • #6331: chore(deps): bump actions/upload-artifact from 5.0.0 to 6.0.0
  • #6332: chore(deps): bump org.mockito:mockito-core from 5.20.0 to 5.21.0
  • #6333: chore(deps): bump actions/download-artifact from 6.0.0 to 7.0.0
  • #6334: chore(deps): bump ruby/setup-ruby ...
Read more