Table of Contents

Previous versions of PMD can be downloaded here: https://github.com/pmd/pmd/releases

30-September-2023 - 7.0.0-rc4

We’re excited to bring you the next major version of PMD!

Since this is a big release, we provide here only a concise version of the release notes. We prepared a separate page with the full Detailed Release Notes for PMD 7.0.0.

ℹ️ Release Candidates

PMD 7.0.0 is finally almost ready. In order to gather feedback, we are going to ship a couple of release candidates. These are officially available on GitHub and Maven Central and can be used as usual (e.g. as a dependency). We encourage you to try out the new features, but keep in mind that we may introduce API breaking changes between the release candidates. It should be stable enough if you don't use custom rules.

We have still some tasks planned for the next release candidates. You can see the progress in PMD 7 Tracking Issue #3898.

If you find any problem or difficulty while updating from PMD 6, please provide feedback via our issue tracker. That way we can improve the experience for all.

Table Of Contents

Changes since 7.0.0-rc3

This section lists the most important changes from the last release candidate. The remaining section describes the complete release notes for 7.0.0.

New and Noteworthy

Migration Guide for PMD 7

A detailed documentation of required changes are available in the Migration Guide for PMD 7.

Apex Jorje Updated

With the new version of Apex Jorje, the new language constructs like User Mode Database Operations can be parsed now. PMD should now be able to parse Apex code up to version 59.0 (Winter ‘23).

Java 21 Support

This release of PMD brings support for Java 21. There are the following new standard language features, that are supported now:

PMD also supports the following preview language features:

In order to analyze a project with PMD that uses these language features, you’ll need to enable it via the environment variable PMD_JAVA_OPTS and select the new language version 21-preview:

export PMD_JAVA_OPTS=--enable-preview
pmd check --use-version java-21-preview ...

Note: Support for Java 19 preview language features have been removed. The version “19-preview” is no longer available.

Fixed issues

  • miscellaneous
    • #4582: [dist] Download link broken
    • #4691: [CVEs] Critical and High CEVs reported on PMD and PMD dependencies
  • core
    • #1204: [core] Allow numeric properties in XML to be within an unbounded range
    • #3919: [core] Merge CPD and PMD language
    • #4204: [core] Provide a CpdAnalysis class as a programmatic entry point into CPD
    • #4301: [core] Remove deprecated property concrete classes
    • #4302: [core] Migrate Property Framework API to Java 8
    • #4323: [core] Refactor CPD integration
    • #4397: [core] Refactor CPD
    • #4611: [core] Fix loading language properties from env vars
    • #4621: [core] Make ClasspathClassLoader::getResource child first
  • cli
    • #4423: [cli] Fix NPE when only --file-list is specified
  • doc
    • #4294: [doc] Migration Guide for upgrading PMD 6 ➡️ 7
    • #4303: [doc] Document new property framework
    • #4521: [doc] Website is not mobile friendly
  • apex
    • #3973: [apex] Update parser to support new ‘as user’ keywords (User Mode for Database Operations)
    • #4453: [apex] [7.0-rc1] Exception while initializing Apexlink (Index 34812 out of bounds for length 34812)
  • apex-design
    • #4596: [apex] ExcessivePublicCount ignores properties
  • apex-security
    • #4646: [apex] ApexSOQLInjection does not recognise SObjectType or SObjectField as safe variable types
  • java
    • #4401: [java] PMD 7 fails to build under Java 19
    • #4583: [java] Support JDK 21 (LTS)
  • java-bestpractices
    • #4634: [java] JUnit4TestShouldUseTestAnnotation false positive with TestNG

API Changes

pmd-java
  • Support for Java 19 preview language features have been removed. The version “19-preview” is no longer available.
Rule properties
  • The old deprecated classes like IntProperty and StringProperty have been removed. Please use PropertyFactory to create properties.
  • All properties which accept multiple values now use a comma (,) as a delimiter. The previous default was a pipe character (|). The delimiter is not configurable anymore. If needed, the comma can be escaped with a backslash.
  • The min and max attributes in property definitions in the XML are now optional and can appear separately or be omitted.
New Programmatic API for CPD

See Detailed Release Notes for PMD 7 and PR #4397 for details.

Removed classes and methods

The following previously deprecated classes have been removed:

  • pmd-core
    • net.sourceforge.pmd.cpd.AbstractTokenizer ➡️ use AnyTokenizer instead
    • net.sourceforge.pmd.cpd.CPD ➡️ use PmdCli from pmd-cli module for CLI support or use CpdAnalysis for programmatic API
    • net.sourceforge.pmd.cpd.GridBagHelper (now package private)
    • net.sourceforge.pmd.cpd.TokenEntry.State
    • net.sourceforge.pmd.lang.document.CpdCompat
    • net.sourceforge.pmd.properties.BooleanMultiProperty
    • net.sourceforge.pmd.properties.BooleanProperty
    • net.sourceforge.pmd.properties.CharacterMultiProperty
    • net.sourceforge.pmd.properties.CharacterProperty
    • net.sourceforge.pmd.properties.DoubleMultiProperty
    • net.sourceforge.pmd.properties.DoubleProperty
    • net.sourceforge.pmd.properties.EnumeratedMultiProperty
    • net.sourceforge.pmd.properties.EnumeratedProperty
    • net.sourceforge.pmd.properties.EnumeratedPropertyDescriptor
    • net.sourceforge.pmd.properties.FileProperty (note: without replacement)
    • net.sourceforge.pmd.properties.FloatMultiProperty
    • net.sourceforge.pmd.properties.FloatProperty
    • net.sourceforge.pmd.properties.IntegerMultiProperty
    • net.sourceforge.pmd.properties.IntegerProperty
    • net.sourceforge.pmd.properties.LongMultiProperty
    • net.sourceforge.pmd.properties.LongProperty
    • net.sourceforge.pmd.properties.MultiValuePropertyDescriptor
    • net.sourceforge.pmd.properties.NumericPropertyDescriptor
    • net.sourceforge.pmd.properties.PropertyDescriptorField
    • net.sourceforge.pmd.properties.RegexProperty
    • net.sourceforge.pmd.properties.SingleValuePropertyDescriptor
    • net.sourceforge.pmd.properties.StringMultiProperty
    • net.sourceforge.pmd.properties.StringProperty
    • net.sourceforge.pmd.properties.ValueParser
    • net.sourceforge.pmd.properties.ValueParserConstants
    • net.sourceforge.pmd.properties.builders.MultiNumericPropertyBuilder
    • net.sourceforge.pmd.properties.builders.MultiPackagedPropertyBuilder
    • net.sourceforge.pmd.properties.builders.MultiValuePropertyBuilder
    • net.sourceforge.pmd.properties.builders.PropertyDescriptorBuilder
    • net.sourceforge.pmd.properties.builders.PropertyDescriptorBuilderConversionWrapper
    • net.sourceforge.pmd.properties.builders.PropertyDescriptorExternalBuilder
    • net.sourceforge.pmd.properties.builders.SingleNumericPropertyBuilder
    • net.sourceforge.pmd.properties.builders.SinglePackagedPropertyBuilder
    • net.sourceforge.pmd.properties.builders.SingleValuePropertyBuilder
    • net.sourceforge.pmd.properties.modules.EnumeratedPropertyModule
    • net.sourceforge.pmd.properties.modules.NumericPropertyModule

The following previously deprecated methods have been removed:

  • pmd-core
    • net.sourceforge.pmd.properties.PropertyBuilder.GenericCollectionPropertyBuilder#delim(char)
    • net.sourceforge.pmd.properties.PropertySource#setProperty(...)
    • net.sourceforge.pmd.properties.PropertyTypeId#factoryFor(...)
    • net.sourceforge.pmd.properties.PropertyTypeId#typeIdFor(...)
    • net.sourceforge.pmd.properties.PropertyDescriptor: removed methods errorFor, type, isMultiValue, uiOrder, compareTo, isDefinedExternally, valueFrom, asDelimitedString

The following methods have been removed:

  • pmd-core
    • CPDConfiguration
      • #sourceCodeFor(File), #postConstruct(), #tokenizer(), #filenameFilter() removed
    • Mark
      • #getSourceSlice(), #setLineCount(int), #getLineCount(), #setSourceCode(SourceCode) removed
      • #getBeginColumn(), #getBeginLine(), #getEndLine(), #getEndColumn() removed ➡️ use getLocation instead
    • Match
      • #LABEL_COMPARATOR removed
      • #setMarkSet(...), #setLabel(...), #getLabel(), #addTokenEntry(...) removed
      • #getSourceCodeSlice() removed ➡️ use CPDReport#getSourceCodeSlice instead
    • TokenEntry
      • #getEOF(), #clearImages(), #getIdentifier(), #getIndex(), #setHashCode(int) removed
      • #EOF removed ➡️ use isEof instead
    • Parser.ParserTask
      • #getFileDisplayName() removed ➡️ use getFileId instead (getFileId().getAbsolutePath())

The following classes have been removed:

  • pmd-core
    • net.sourceforge.pmd.cpd.AbstractLanguage
    • net.sourceforge.pmd.cpd.AnyLanguage
    • net.sourceforge.pmd.cpd.Language
    • net.sourceforge.pmd.cpd.LanguageFactory
    • net.sourceforge.pmd.cpd.MatchAlgorithm (now package private)
    • net.sourceforge.pmd.cpd.MatchCollector (now package private)
    • net.sourceforge.pmd.cpd.SourceCode (and all inner classes like FileCodeLoader, …)
    • net.sourceforge.pmd.cpd.token.TokenFilter
Moved packages
  • pmd-core
    • NumericConstraints (old package: net.sourceforge.pmd.properties.constraints.NumericConstraints)
    • PropertyConstraint (old package: net.sourceforge.pmd.properties.constraints.PropertyConstraint)
      • not experimental anymore
    • ReportException (old package: net.sourceforge.pmd.cpd, moved to module pmd-ant)
      • it is now a RuntimeException
    • CPDReportRenderer (old package: net.sourceforge.pmd.cpd.renderer)
    • AntlrTokenFilter (old package: net.sourceforge.pmd.cpd.token)
    • BaseTokenFilter (old package: net.sourceforge.pmd.cpd.token.internal)
    • JavaCCTokenFilter (old package: net.sourceforge.pmd.cpd.token)
Changed types and other changes
Internal APIs
Deprecated API
Experimental APIs

External Contributions

  • #4528: [apex] Update to apexlink - Kevin Jones (@nawforce)
  • #4637: [java] fix #4634 - JUnit4TestShouldUseTestAnnotation false positive with TestNG - Krystian Dabrowski (@krdabrowski)
  • #4649: [apex] Add SObjectType and SObjectField to list of injectable SOQL variable types - Richard Corfield (@rcorfieldffdc)
  • #4651: [doc] Add “Tencent Cloud Code Analysis” in Tools / Integrations - yale (@cyw3)
  • #4664: [cli] CPD: Fix NPE when only --file-list is specified - Wener (@wener-tiobe)
  • #4665: [java] Doc: Fix references AutoClosable -> AutoCloseable - Andrey Bozhko (@AndreyBozhko)

🚀 Major Features and Enhancements

The new official logo of PMD:

New PMD Logo

Revamped Java module

  • Java grammar substantially refactored - more correct regarding the Java Language Specification (JLS)
  • Built-in rules have been upgraded for the changed AST
  • Rewritten type resolution framework and symbol table correctly implements the JLS
  • AST exposes more semantic information (method calls, field accesses)

For more information, see the Detailed Release Notes for PMD 7.

Contributors: Clément Fournier (@oowekyala), Andreas Dangel (@adangel), Juan Martín Sotuyo Dodero (@jsotuyod)

Revamped Command Line Interface

  • unified and consistent Command Line Interface for both Linux/Unix and Windows across our different utilities
  • single script pmd (pmd.bat for Windows) to launch the different utilities:
    • pmd check to run PMD rules and analyze a project
    • pmd cpd to run CPD (copy paste detector)
    • pmd designer to run the PMD Rule Designer
  • progress bar support for pmd check
  • shell completion

Demo

For more information, see the Detailed Release Notes for PMD 7.

Contributors: Juan Martín Sotuyo Dodero (@jsotuyod)

Full Antlr support

  • Antlr based grammars can now be used to build full-fledged PMD rules.
  • Previously, Antlr grammar could only be used for CPD
  • New supported languages: Swift and Kotlin

For more information, see the Detailed Release Notes for PMD 7.

Contributors: Lucas Soncini (@lsoncini), Matías Fraga (@matifraga), Tomás De Lucca (@tomidelucca)

Updated PMD Designer

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

New CPD report format cpdhtml-v2.xslt

Thanks to @mohan-chinnappan-n a new CPD report format has been added which features a data table. It uses an XSLT stylesheet to convert CPD’s XML format into HTML.

See the example report.

Note that this is just a concise listing of the highlight. For more information on the languages, see the Detailed Release Notes for PMD 7.

New: Swift support

  • use PMD to analyze Swift code with PMD rules
  • initially 4 built-in rules

Contributors: Lucas Soncini (@lsoncini), Matías Fraga (@matifraga), Tomás De Lucca (@tomidelucca)

New: Kotlin support (experimental)

  • use PMD to analyze Kotlin code with PMD rules
  • Support for Kotlin 1.8 grammar
  • initially 2 built-in rules

New: CPD support for TypeScript

Thanks to a contribution, CPD now supports the TypeScript language. It is shipped with the rest of the JavaScript support in the module pmd-javascript.

Contributors: Paul Guyot (@pguyot)

New: CPD support for Julia

Thanks to a contribution, CPD now supports the Julia language. It is shipped in the new module pmd-julia.

Contributors: Wener (@wener-tiobe)

New: CPD support for Coco

Thanks to a contribution, CPD now supports Coco, a modern programming language designed specifically for building event-driven software. It is shipped in the new module pmd-coco.

Contributors: Wener (@wener-tiobe)

New: Java 21 Support

This release of PMD brings support for Java 21. There are the following new standard language features, that are supported now:

PMD also supports the following preview language features:

In order to analyze a project with PMD that uses these language features, you’ll need to enable it via the environment variable PMD_JAVA_OPTS and select the new language version 21-preview:

export PMD_JAVA_OPTS=--enable-preview
pmd check --use-version java-21-preview ...

Note: Support for Java 19 preview language features have been removed. The version “19-preview” is no longer available.

Changed: JavaScript support

  • latest version supports ES6 and also some new constructs (see Rhino])
  • comments are retained

Changed: Language versions

  • more predefined language versions for each supported language
  • can be used to limit rule execution for specific versions only with minimumLanguageVersion and maximumLanguageVersion attributes.

Changed: CPP can now ignore identifiers in sequences (CPD)

  • new command line option for CPD: --ignore-sequences.
  • This option is used for CPP only: with the already existing option --ignore-literal-sequences, only literals were ignored. The new option additional ignores identifiers as well in sequences.
  • See PR #4470 for details.

Changed: Apex Jorje Updated

With the new version of Apex Jorje, the new language constructs like User Mode Database Operations can be parsed now. PMD should now be able to parse Apex code up to version 59.0 (Winter ‘23).

Changed: Rule properties

  • The old deprecated classes like IntProperty and StringProperty have been removed. Please use PropertyFactory to create properties.
  • All properties which accept multiple values now use a comma (,) as a delimiter. The previous default was a pipe character (|). The delimiter is not configurable anymore. If needed, the comma can be escaped with a backslash.
  • The min and max attributes in property definitions in the XML are now optional and can appear separately or be omitted.

🌟 New and changed rules

New Rules

Apex

Java

  • UnnecessaryBoxing reports boxing and unboxing conversions that may be made implicit.

Kotlin

Swift

Changed Rules

General changes

Apex General changes

  • The properties cc_categories, cc_remediation_points_multiplier, cc_block_highlighting have been removed from all rules. These properties have been deprecated since PMD 6.13.0. See issue #1648 for more details.

Java General changes

  • Violations reported on methods or classes previously reported the line range of the entire method or class. With PMD 7.0.0, the reported location is now just the identifier of the method or class. This affects various rules, e.g. CognitiveComplexity.

    The report location is controlled by the overrides of the method getReportLocation in different node types.

    See issue #4439 and issue #730 for more details.

Java Best Practices

  • ArrayIsStoredDirectly: Violations are now reported on the assignment and not anymore on the formal parameter. The reported line numbers will probably move.
  • AvoidReassigningLoopVariables: This rule might not report anymore all reassignments of the control variable in for-loops when the property forReassign is set to skip. See issue #4500 for more details.
  • LooseCoupling: The rule has a new property to allow some types to be coupled to (allowedTypes).
  • UnusedLocalVariable: This rule has some important false-negatives fixed and finds many more cases now. For details see issues #2130, #4516, and #4517.

Java Codestyle

  • MethodNamingConventions: The property checkNativeMethods has been removed. The property was deprecated since PMD 6.3.0. Use the property nativePattern to control whether native methods should be considered or not.
  • ShortVariable: This rule now also reports short enum constant names.
  • UseDiamondOperator: The property java7Compatibility has been removed. The rule now handles Java 7 properly without a property.
  • UnnecessaryFullyQualifiedName: The rule has two new properties, to selectively disable reporting on static field and method qualifiers. The rule also has been improved to be more precise.
  • UselessParentheses: The rule has two new properties which control how strict the rule should be applied. With ignoreClarifying (default: true) parentheses that are strictly speaking not necessary are allowed, if they separate expressions of different precedence. The other property ignoreBalancing (default: true) is similar, in that it allows parentheses that help reading and understanding the expressions.

Java Design

  • CyclomaticComplexity: The property reportLevel has been removed. The property was deprecated since PMD 6.0.0. The report level can now be configured separated for classes and methods using classReportLevel and methodReportLevel instead.
  • ImmutableField: The property ignoredAnnotations has been removed. The property was deprecated since PMD 6.52.0.
  • LawOfDemeter: The rule has a new property trustRadius. This defines the maximum degree of trusted data. The default of 1 is the most restrictive.
  • NPathComplexity: The property minimum has been removed. It was deprecated since PMD 6.0.0. Use the property reportLevel instead.
  • SingularField: The properties checkInnerClasses and disallowNotAssignment have been removed. The rule is now more precise and will check these cases properly.
  • UseUtilityClass: The property ignoredAnnotations has been removed.

Java Documentation

  • CommentContent: The properties caseSensitive and disallowedTerms are removed. The new property forbiddenRegex can be used now to define the disallowed terms with a single regular expression.
  • CommentRequired:
    • Overridden methods are now detected even without the @Override annotation. This is relevant for the property methodWithOverrideCommentRequirement. See also pull request #3757.
    • Elements in annotation types are now detected as well. This might lead to an increased number of violations for missing public method comments.
  • CommentSize: When determining the line-length of a comment, the leading comment prefix markers (e.g. * or //) are ignored and don’t add up to the line-length. See also pull request #4369.

Java Error Prone

  • AvoidDuplicateLiterals: The property exceptionfile has been removed. The property was deprecated since PMD 6.10.0. Use the property exceptionList instead.
  • DontImportSun: sun.misc.Signal is not special-cased anymore.
  • EmptyCatchBlock: CloneNotSupportedException and InterruptedException are not special-cased anymore. Rename the exception parameter to ignored to ignore them.
  • ImplicitSwitchFallThrough: Violations are now reported on the case statements rather than on the switch statements. This is more accurate but might result in more violations now.

Removed Rules

Many rules, that were previously deprecated have been finally removed. See Detailed Release Notes for PMD 7 for the complete list.

🚨 API

The API of PMD has been growing over the years and needed some cleanup. The goal is, to have a clear separation between a well-defined API and the implementation, which is internal. This should help us in future development.

Also, there are some improvement and changes in different areas. For the detailed description of the changes listed here, see Detailed Release Notes for PMD 7.

  • Miscellaneous smaller changes and cleanups
  • XPath 3.1 support for XPath-based rules
  • Node stream API for AST traversal
  • Metrics framework
  • Testing framework
  • Language Lifecycle and Language Properties
  • Rule Properties
  • New Programmatic API for CPD

💥 Compatibility and migration notes

A detailed documentation of required changes are available in the Migration Guide for PMD 7.

See also Detailed Release Notes for PMD 7.

🐛 Fixed Issues

  • miscellaneous
    • #881: [all] Breaking API changes for 7.0.0
    • #896: [all] Use slf4j
    • #1431: [ui] Remove old GUI applications (designerold, bgastviewer)
    • #1451: [core] RulesetFactoryCompatibility stores the whole ruleset file in memory as a string
    • #2496: Update PMD 7 Logo on landing page
    • #2497: PMD 7 Logo page
    • #2498: Update PMD 7 Logo in documentation
    • #3797: [all] Use JUnit5
    • #4462: Provide Software Bill of Materials (SBOM)
    • #4460: Fix assembly-plugin warnings
    • #4582: [dist] Download link broken
    • #4691: [CVEs] Critical and High CEVs reported on PMD and PMD dependencies
  • ant
    • #4080: [ant] Split off Ant integration into a new submodule
  • core
    • #880: [core] Make visitors generic
    • #1204: [core] Allow numeric properties in XML to be within an unbounded range
    • #1622: [core] NodeStream API
    • #1687: [core] Deprecate and Remove XPath 1.0 support
    • #1785: [core] Allow abstract node types to be valid rulechain visits
    • #1825: [core] Support NoAttribute for XPath
    • #2038: [core] Remove DCD
    • #2218: [core] isFindBoundary should not be an attribute
    • #2234: [core] Consolidate PMD CLI into a single command
    • #2239: [core] Merging Javacc build scripts
    • #2500: [core] Clarify API for ANTLR based languages
    • #2518: [core] Language properties
    • #2602: [core] Remove ParserOptions
    • #2614: [core] Upgrade Saxon, add XPath 3.1, remove Jaxen
    • #2696: [core] Remove DFA
    • #2821: [core] Rule processing error filenames are missing paths
    • #2873: [core] Utility classes in pmd 7
    • #2885: [core] Error recovery mode
    • #3203: [core] Replace RuleViolationFactory implementations with ViolationDecorator
    • #3692: [core] Analysis listeners
    • #3782: [core] Language lifecycle
    • #3815: [core] Update Saxon HE to 10.7
    • #3893: [core] Text documents
    • #3902: [core] Violation decorators
    • #3918: [core] Make LanguageRegistry non static
    • #3919: [core] Merge CPD and PMD language
    • #3922: [core] Better error reporting for the ruleset parser
    • #4035: [core] ConcurrentModificationException in DefaultRuleViolationFactory
    • #4120: [core] Explicitly name all language versions
    • #4204: [core] Provide a CpdAnalysis class as a programmatic entry point into CPD
    • #4301: [core] Remove deprecated property concrete classes
    • #4302: [core] Migrate Property Framework API to Java 8
    • #4323: [core] Refactor CPD integration
    • #4353: [core] Micro optimizations for Node API
    • #4365: [core] Improve benchmarking
    • #4397: [core] Refactor CPD
    • #4420: [core] Remove PMD.EOL
    • #4425: [core] Replace TextFile::pathId
    • #4454: [core] “Unknown option: ‘-min’” but is referenced in documentation
    • #4611: [core] Fix loading language properties from env vars
    • #4621: [core] Make ClasspathClassLoader::getResource child first
  • cli
    • #2234: [core] Consolidate PMD CLI into a single command
    • #3828: [core] Progress reporting
    • #4079: [cli] Split off CLI implementation into a pmd-cli submodule
    • #4423: [cli] Fix NPE when only --file-list is specified
    • #4482: [cli] pmd.bat can only be executed once
    • #4484: [cli] ast-dump with no properties produce an NPE
  • doc
    • #2501: [doc] Verify ANTLR Documentation
    • #4294: [doc] Migration Guide for upgrading PMD 6 ➡️ 7
    • #4303: [doc] Document new property framework
    • #4438: [doc] Documentation links in VS Code are outdated
    • #4521: [doc] Website is not mobile friendly
  • testing
    • #2435: [test] Remove duplicated Dummy language module
    • #4234: [test] Tests that change the logging level do not work

Language specific fixes:

  • apex
    • #1937: [apex] Apex should only have a single RootNode
    • #1648: [apex,vf] Remove CodeClimate dependency
    • #1750: [apex] Remove apex statistical rules
    • #2836: [apex] Remove Apex ProjectMirror
    • #3973: [apex] Update parser to support new ‘as user’ keywords (User Mode for Database Operations)
    • #4427: [apex] ApexBadCrypto test failing to detect inline code
    • #4453: [apex] [7.0-rc1] Exception while initializing Apexlink (Index 34812 out of bounds for length 34812)
  • apex-design
    • #2667: [apex] Integrate nawforce/ApexLink to build robust Unused rule
    • #4509: [apex] ExcessivePublicCount doesn’t consider inner classes correctly
    • #4596: [apex] ExcessivePublicCount ignores properties
  • apex-security
    • #4646: [apex] ApexSOQLInjection does not recognise SObjectType or SObjectField as safe variable types
  • java
    • #520: [java] Allow @SuppressWarnings with constants instead of literals
    • #864: [java] Similar/duplicated implementations for determining FQCN
    • #905: [java] Add new node for anonymous class declaration
    • #910: [java] AST inconsistency between primitive and reference type arrays
    • #997: [java] Java8 parsing corner case with annotated array types
    • #998: [java] AST inconsistencies around FormalParameter
    • #1019: [java] Breaking Java Grammar changes for PMD 7.0.0
    • #1124: [java] ImmutableList implementation in the qname codebase
    • #1128: [java] Improve ASTLocalVariableDeclaration
    • #1150: [java] ClassOrInterfaceType AST improvements
    • #1207: [java] Resolve explicit types using FQCNs, without hitting the classloader
    • #1367: [java] Parsing error on annotated inner class
    • #1661: [java] About operator nodes
    • #2366: [java] Remove qualified names
    • #2819: [java] GLB bugs in pmd 7
    • #3642: [java] Parse error on rare extra dimensions on method return type on annotation methods
    • #3763: [java] Ambiguous reference error in valid code
    • #3749: [java] Improve isOverridden in ASTMethodDeclaration
    • #3750: [java] Make symbol table support instanceof pattern bindings
    • #3752: [java] Expose annotations in symbol API
    • #4237: [java] Cleanup handling of Java comments
    • #4317: [java] Some AST nodes should not be TypeNodes
    • #4359: [java] Type resolution fails with NPE when the scope is not a type declaration
    • #4367: [java] Move testrule TypeResTest into internal
    • #4383: [java] IllegalStateException: Object is not an array type!
    • #4401: [java] PMD 7 fails to build under Java 19
    • #4405: [java] Processing error with ArrayIndexOutOfBoundsException
    • #4583: [java] Support JDK 21 (LTS)
  • java-bestpractices
    • #342: [java] AccessorMethodGeneration: Name clash with another public field not properly handled
    • #755: [java] AccessorClassGeneration false positive for private constructors
    • #770: [java] UnusedPrivateMethod yields false positive for counter-variant arguments
    • #807: [java] AccessorMethodGeneration false positive with overloads
    • #833: [java] ForLoopCanBeForeach should consider iterating on this
    • #1189: [java] UnusedPrivateMethod false positive from inner class via external class
    • #1205: [java] Improve ConstantsInInterface message to mention alternatives
    • #1212: [java] Don’t raise JUnitTestContainsTooManyAsserts on JUnit 5’s assertAll
    • #1422: [java] JUnitTestsShouldIncludeAssert false positive with inherited @Rule field
    • #1455: [java] JUnitTestsShouldIncludeAssert: False positives for assert methods named “check” and “verify”
    • #1563: [java] ForLoopCanBeForeach false positive with method call using index variable
    • #1565: [java] JUnitAssertionsShouldIncludeMessage false positive with AssertJ
    • #1747: [java] PreserveStackTrace false-positive
    • #1969: [java] MissingOverride false-positive triggered by package-private method overwritten in another package by extending class
    • #1998: [java] AccessorClassGeneration false-negative: subclass calls private constructor
    • #2130: [java] UnusedLocalVariable: false-negative with array
    • #2147: [java] JUnitTestsShouldIncludeAssert - false positives with lambdas and static methods
    • #2464: [java] LooseCoupling must ignore class literals: ArrayList.class
    • #2542: [java] UseCollectionIsEmpty can not detect the case foo.bar().size()
    • #2650: [java] UseTryWithResources false positive when AutoCloseable helper used
    • #2796: [java] UnusedAssignment false positive with call chains
    • #2797: [java] MissingOverride long-standing issues
    • #2806: [java] SwitchStmtsShouldHaveDefault false-positive with Java 14 switch non-fallthrough branches
    • #2822: [java] LooseCoupling rule: Extend to cover user defined implementations and interfaces
    • #2843: [java] Fix UnusedAssignment FP with field accesses
    • #2882: [java] UseTryWithResources - false negative for explicit close
    • #2883: [java] JUnitAssertionsShouldIncludeMessage false positive with method call
    • #2890: [java] UnusedPrivateMethod false positive with generics
    • #2946: [java] SwitchStmtsShouldHaveDefault false positive on enum inside enums
    • #3672: [java] LooseCoupling - fix false positive with generics
    • #3675: [java] MissingOverride - fix false positive with mixing type vars
    • #3858: [java] UseCollectionIsEmpty should infer local variable type from method invocation
    • #4433: [java] [7.0-rc1] ReplaceHashtableWithMap on java.util.Properties
    • #4492: [java] GuardLogStatement gives false positive when argument is a Java method reference
    • #4503: [java] JUnitTestsShouldIncludeAssert: false negative with TestNG
    • #4516: [java] UnusedLocalVariable: false-negative with try-with-resources
    • #4517: [java] UnusedLocalVariable: false-negative with compound assignments
    • #4518: [java] UnusedLocalVariable: false-positive with multiple for-loop indices
    • #4634: [java] JUnit4TestShouldUseTestAnnotation false positive with TestNG
  • java-codestyle
    • #1208: [java] PrematureDeclaration rule false-positive on variable declared to measure time
    • #1429: [java] PrematureDeclaration as result of method call (false positive)
    • #1480: [java] IdenticalCatchBranches false positive with return expressions
    • #1673: [java] UselessParentheses false positive with conditional operator
    • #1790: [java] UnnecessaryFullyQualifiedName false positive with enum constant
    • #1918: [java] UselessParentheses false positive with boolean operators
    • #2134: [java] PreserveStackTrace not handling Throwable.addSuppressed(...)
    • #2299: [java] UnnecessaryFullyQualifiedName false positive with similar package name
    • #2391: [java] UseDiamondOperator FP when expected type and constructed type have a different parameterization
    • #2528: [java] MethodNamingConventions - JUnit 5 method naming not support ParameterizedTest
    • #2739: [java] UselessParentheses false positive for string concatenation
    • #2748: [java] UnnecessaryCast false positive with unchecked cast
    • #2973: [java] New rule: UnnecessaryBoxing
    • #3195: [java] Improve rule UnnecessaryReturn to detect more cases
    • #3218: [java] Generalize UnnecessaryCast to flag all unnecessary casts
    • #3221: [java] PrematureDeclaration false positive for unused variables
    • #3238: [java] Improve ExprContext, fix FNs of UnnecessaryCast
    • #3500: [java] UnnecessaryBoxing - check for Integer.valueOf(String) calls
    • #4268: [java] CommentDefaultAccessModifier: false positive with TestNG annotations
    • #4273: [java] CommentDefaultAccessModifier ignoredAnnotations should include “org.junit.jupiter.api.extension.RegisterExtension” by default
    • #4357: [java] Fix IllegalStateException in UseDiamondOperator rule
    • #4432: [java] [7.0-rc1] UnnecessaryImport - Unused static import is being used
    • #4455: [java] FieldNamingConventions: false positive with lombok’s @UtilityClass
    • #4487: [java] UnnecessaryConstructor: false-positive with @Inject and @Autowired
    • #4511: [java] LocalVariableCouldBeFinal shouldn’t report unused variables
    • #4512: [java] MethodArgumentCouldBeFinal shouldn’t report unused parameters
    • #4557: [java] UnnecessaryImport FP with static imports of overloaded methods
  • java-design
    • #1014: [java] LawOfDemeter: False positive with lambda expression
    • #1605: [java] LawOfDemeter: False positive for standard UTF-8 charset name
    • #2160: [java] Issues with Law of Demeter
    • #2175: [java] LawOfDemeter: False positive for chained methods with generic method call
    • #2179: [java] LawOfDemeter: False positive with static property access - should treat class-level property as global object, not dot-accessed property
    • #2180: [java] LawOfDemeter: False positive with Thread and ThreadLocalRandom
    • #2182: [java] LawOfDemeter: False positive with package-private access
    • #2188: [java] LawOfDemeter: False positive with fields assigned to local vars
    • #2536: [java] ClassWithOnlyPrivateConstructorsShouldBeFinal can’t detect inner class
    • #3668: [java] ClassWithOnlyPrivateConstructorsShouldBeFinal - fix FP with inner private classes
    • #3754: [java] SingularField false positive with read in while condition
    • #3786: [java] SimplifyBooleanReturns should consider operator precedence
    • #3840: [java] LawOfDemeter disallows method call on locally created object
    • #4238: [java] Make LawOfDemeter not use the rulechain
    • #4254: [java] ImmutableField - false positive with Lombok @Setter
    • #4434: [java] [7.0-rc1] ExceptionAsFlowControl when simply propagating
    • #4456: [java] FinalFieldCouldBeStatic: false positive with lombok’s @UtilityClass
    • #4477: [java] SignatureDeclareThrowsException: false-positive with TestNG annotations
    • #4490: [java] ImmutableField - false negative with Lombok @Getter
    • #4549: [java] Make LawOfDemeter results deterministic
  • java-documentation
    • #4369: [java] Improve CommentSize
    • #4416: [java] Fix reported line number in CommentContentRule
  • java-errorprone
    • #659: [java] MissingBreakInSwitch - last default case does not contain a break
    • #1005: [java] CloneMethodMustImplementCloneable triggers for interfaces
    • #1669: [java] NullAssignment - FP with ternay and null as constructor argument
    • #1899: [java] Recognize @SuppressWanings(“fallthrough”) for MissingBreakInSwitch
    • #2320: [java] NullAssignment - FP with ternary and null as method argument
    • #2532: [java] AvoidDecimalLiteralsInBigDecimalConstructor can not detect the case new BigDecimal(Expression)
    • #2579: [java] MissingBreakInSwitch detects the lack of break in the last case
    • #2880: [java] CompareObjectsWithEquals - false negative with type res
    • #2893: [java] Remove special cases from rule EmptyCatchBlock
    • #2894: [java] Improve MissingBreakInSwitch
    • #3071: [java] BrokenNullCheck FP with PMD 6.30.0
    • #3087: [java] UnnecessaryBooleanAssertion overlaps with SimplifiableTestAssertion
    • #3100: [java] UseCorrectExceptionLogging FP in 6.31.0
    • #3173: [java] UseProperClassLoader false positive
    • #3351: [java] ConstructorCallsOverridableMethod ignores abstract methods
    • #3400: [java] AvoidUsingOctalValues FN with underscores
    • #3843: [java] UseEqualsToCompareStrings should consider return type
    • #4063: [java] AvoidBranchingStatementAsLastInLoop: False-negative about try/finally block
    • #4356: [java] Fix NPE in CloseResourceRule
    • #4449: [java] AvoidAccessibilityAlteration: Possible false positive in AvoidAccessibilityAlteration rule when using Lambda expression
    • #4457: [java] OverrideBothEqualsAndHashcode: false negative with anonymous classes
    • #4493: [java] MissingStaticMethodInNonInstantiatableClass: false-positive about @Inject
    • #4505: [java] ImplicitSwitchFallThrough NPE in PMD 7.0.0-rc1
    • #4510: [java] ConstructorCallsOverridableMethod: false positive with lombok’s @Value
    • #4513: [java] UselessOperationOnImmutable various false negatives with String
    • #4514: [java] AvoidLiteralsInIfCondition false positive and negative for String literals when ignoreExpressions=true
    • #4546: [java] OverrideBothEqualsAndHashCode ignores records
  • java-multithreading
    • #2537: [java] DontCallThreadRun can’t detect the case that call run() in this.run()
    • #2538: [java] DontCallThreadRun can’t detect the case that call run() in foo.bar.run()
    • #2577: [java] UseNotifyAllInsteadOfNotify falsely detect a special case with argument: foo.notify(bar)
    • #4483: [java] NonThreadSafeSingleton false positive with double-checked locking
  • java-performance
    • #1224: [java] InefficientEmptyStringCheck false negative in anonymous class
    • #2587: [java] AvoidArrayLoops could also check for list copy through iterated List.add()
    • #2712: [java] SimplifyStartsWith false-positive with AssertJ
    • #3486: [java] InsufficientStringBufferDeclaration: Fix NPE
    • #3848: [java] StringInstantiation: false negative when using method result
    • #4070: [java] A false positive about the rule RedundantFieldInitializer
    • #4458: [java] RedundantFieldInitializer: false positive with lombok’s @Value
  • kotlin
    • #419: [kotlin] Add support for Kotlin
    • #4389: [kotlin] Update grammar to version 1.8
  • swift
    • #1877: [swift] Feature/swift rules
    • #1882: [swift] UnavailableFunction Swift rule
  • xml
    • #1800: [xml] Unimplement org.w3c.dom.Node from the XmlNodeWrapper

✨ External Contributions

  • #1658: [core] Node support for Antlr-based languages - Matías Fraga (@matifraga)
  • #1698: [core] [swift] Antlr Base Parser adapter and Swift Implementation - Lucas Soncini (@lsoncini)
  • #1774: [core] Antlr visitor rules - Lucas Soncini (@lsoncini)
  • #1877: [swift] Feature/swift rules - Matías Fraga (@matifraga)
  • #1881: [doc] Add ANTLR documentation - Matías Fraga (@matifraga)
  • #1882: [swift] UnavailableFunction Swift rule - Tomás de Lucca (@tomidelucca)
  • #2830: [apex] Apexlink POC - Kevin Jones (@nawforce)
  • #3866: [core] Add CLI Progress Bar - @JerritEic (@JerritEic)
  • #4402: [javascript] CPD: add support for Typescript using antlr4 grammar - Paul Guyot (@pguyot)
  • #4403: [julia] CPD: Add support for Julia code duplication - Wener (@wener-tiobe)
  • #4412: [doc] Added new error msg to ConstantsInInterface - David Ljunggren (@dague1)
  • #4426: [cpd] New XML to HTML XLST report format for PMD CPD - mohan-chinnappan-n (@mohan-chinnappan-n)
  • #4428: [apex] ApexBadCrypto bug fix for #4427 - inline detection of hard coded values - Steven Stearns (@sfdcsteve)
  • #4431: [coco] CPD: Coco support for code duplication detection - Wener (@wener-tiobe)
  • #4444: [java] CommentDefaultAccessModifier - ignore org.junit.jupiter.api.extension.RegisterExtension by default - Nirvik Patel (@nirvikpatel)
  • #4450: [java] Fix #4449 AvoidAccessibilityAlteration: Correctly handle Lambda expressions in PrivilegedAction scenarios - Seren (@mohui1999)
  • #4452: [doc] Update PMD_APEX_ROOT_DIRECTORY documentation reference - nwcm (@nwcm)
  • #4470: [cpp] CPD: Added strings as literal and ignore identifiers in sequences - Wener (@wener-tiobe)
  • #4474: [java] ImmutableField: False positive with lombok (fixes #4254) - Pim van der Loos (@PimvanderLoos)
  • #4488: [java] Fix #4477: A false-positive about SignatureDeclareThrowsException - AnnaDev (@LynnBroe)
  • #4494: [java] Fix #4487: A false-positive about UnnecessaryConstructor and @Inject and @Autowired - AnnaDev (@LynnBroe)
  • #4495: [java] Fix #4493: false-positive about MissingStaticMethodInNonInstantiatableClass and @Inject - AnnaDev (@LynnBroe)
  • #4507: [java] Fix #4503: A false negative about JUnitTestsShouldIncludeAssert and testng - AnnaDev (@LynnBroe)
  • #4520: [doc] Fix typo: missing closing quotation mark after CPD-END - João Dinis Ferreira (@joaodinissf)
  • #4528: [apex] Update to apexlink - Kevin Jones (@nawforce)
  • #4533: [java] Fix #4063: False-negative about try/catch block in Loop - AnnaDev (@LynnBroe)
  • #4536: [java] Fix #4268: CommentDefaultAccessModifier - false positive with TestNG’s @Test annotation - AnnaDev (@LynnBroe)
  • #4537: [java] Fix #4455: A false positive about FieldNamingConventions and UtilityClass - AnnaDev (@LynnBroe)
  • #4538: [java] Fix #4456: A false positive about FinalFieldCouldBeStatic and UtilityClass - AnnaDev (@LynnBroe)
  • #4540: [java] Fix #4457: false negative about OverrideBothEqualsAndHashcode - AnnaDev (@LynnBroe)
  • #4541: [java] Fix #4458: A false positive about RedundantFieldInitializer and @Value - AnnaDev (@LynnBroe)
  • #4542: [java] Fix #4510: A false positive about ConstructorCallsOverridableMethod and @Value - AnnaDev (@LynnBroe)
  • #4553: [java] Fix #4492: GuardLogStatement gives false positive when argument is a Java method reference - Anastasiia Koba (@anastasiia-koba)
  • #4637: [java] fix #4634 - JUnit4TestShouldUseTestAnnotation false positive with TestNG - Krystian Dabrowski (@krdabrowski)
  • #4649: [apex] Add SObjectType and SObjectField to list of injectable SOQL variable types - Richard Corfield (@rcorfieldffdc)
  • #4651: [doc] Add “Tencent Cloud Code Analysis” in Tools / Integrations - yale (@cyw3)
  • #4664: [cli] CPD: Fix NPE when only --file-list is specified - Wener (@wener-tiobe)
  • #4665: [java] Doc: Fix references AutoClosable -> AutoCloseable - Andrey Bozhko (@AndreyBozhko)

📈 Stats

  • 5007 commits
  • 658 closed tickets & PRs
  • Days since last release: 122

30-May-2023 - 7.0.0-rc3

We’re excited to bring you the next major version of PMD!

Since this is a big release, we provide here only a concise version of the release notes. We prepared a separate page with the full Detailed Release Notes for PMD 7.0.0.

ℹ️ Release Candidates

PMD 7.0.0 is finally almost ready. In order to gather feedback, we are going to ship a couple of release candidates. These are officially available on GitHub and Maven Central and can be used as usual (e.g. as a dependency). We encourage you to try out the new features, but keep in mind that we may introduce API breaking changes between the release candidates. It should be stable enough if you don't use custom rules.

We have still some tasks planned for the next release candidates. You can see the progress in PMD 7 Tracking Issue #3898.

If you find any problem or difficulty while updating from PMD 6, please provide feedback via our issue tracker. That way we can improve the experience for all.

Table Of Contents

Changes since 7.0.0-rc2

This section lists the most important changes from the last release candidate. The remaining section describes the complete release notes for 7.0.0.

New CPD report format cpdhtml-v2.xslt

Thanks to @mohan-chinnappan-n a new CPD report format has been added which features a data table. It uses an XSLT stylesheet to convert CPD’s XML format into HTML.

See the example report.

Fixed issues

  • miscellaneous
    • #4460: Fix assembly-plugin warnings
  • core
    • #4425: [core] Replace TextFile::pathId
    • #4454: [core] “Unknown option: ‘-min’” but is referenced in documentation
  • java-bestpractices
    • #4433: [java] [7.0-rc1] ReplaceHashtableWithMap on java.util.Properties
    • #4492: [java] GuardLogStatement gives false positive when argument is a Java method reference
    • #4503: [java] JUnitTestsShouldIncludeAssert: false negative with TestNG
  • java-codestyle
    • #4268: [java] CommentDefaultAccessModifier: false positive with TestNG annotations
    • #4432: [java] [7.0-rc1] UnnecessaryImport - Unused static import is being used
    • #4455: [java] FieldNamingConventions: false positive with lombok’s @UtilityClass
    • #4557: [java] UnnecessaryImport FP with static imports of overloaded methods
  • java-design
    • #4434: [java] [7.0-rc1] ExceptionAsFlowControl when simply propagating
    • #4456: [java] FinalFieldCouldBeStatic: false positive with lombok’s @UtilityClass
    • #4549: [java] Make LawOfDemeter results deterministic
  • java-errorprone
    • #4063: [java] AvoidBranchingStatementAsLastInLoop: False-negative about try/finally block
    • #4457: [java] OverrideBothEqualsAndHashcode: false negative with anonymous classes
    • #4510: [java] ConstructorCallsOverridableMethod: false positive with lombok’s @Value
    • #4546: [java] OverrideBothEqualsAndHashCode ignores records
  • java-performance
    • #4458: [java] RedundantFieldInitializer: false positive with lombok’s @Value

API Changes

  • The following previously deprecated classes have been removed:
    • pmd-core
      • net.sourceforge.pmd.PMD
      • net.sourceforge.pmd.cli.PMDCommandLineInterface
      • net.sourceforge.pmd.cli.PMDParameters
      • net.sourceforge.pmd.cli.PmdParametersParseResult
  • The asset filenames of PMD on GitHub Releases are now pmd-dist-<version>-bin.zip, pmd-dist-<version>-src.zip and pmd-dist-<version>-doc.zip. Keep that in mind, if you have an automated download script.

    The structure inside the ZIP files stay the same, e.g. we still provide inside the binary distribution ZIP file the base directory pmd-bin-<version>.

  • The CLI option --stress (or -stress) has been removed without replacement.
  • The CLI option --minimum-priority was changed with 7.0.0-rc1 to only take the following values: High, Medium High, Medium, Medium Low, Low. With 7.0.0-rc2 compatibility has been restored, so that the equivalent integer values (1 to 5) are supported as well.
  • Replaced RuleViolation::getFilename with new RuleViolation#getFileId, that returns a FileId. This is an identifier for a TextFile and could represent a path name. This allows to have a separate display name, e.g. renderers use FileNameRenderer to either display the full path name or a relative path name (see Renderer#setFileNameRenderer and ConfigurableFileNameRenderer). Many places where we used a simple String for a path-like name before have been adapted to use the new FileId.

    See PR #4425 for details.

External Contributions

  • #4426: [cpd] New XML to HTML XLST report format for PMD CPD - mohan-chinnappan-n (@mohan-chinnappan-n)
  • #4431: [coco] CPD: Coco support for code duplication detection - Wener (@wener-tiobe)
  • #4470: [cpp] CPD: Added strings as literal and ignore identifiers in sequences - Wener (@wener-tiobe)
  • #4507: [java] Fix #4503: A false negative about JUnitTestsShouldIncludeAssert and testng - AnnaDev (@LynnBroe)
  • #4533: [java] Fix #4063: False-negative about try/catch block in Loop - AnnaDev (@LynnBroe)
  • #4536: [java] Fix #4268: CommentDefaultAccessModifier - false positive with TestNG’s @Test annotation - AnnaDev (@LynnBroe)
  • #4537: [java] Fix #4455: A false positive about FieldNamingConventions and UtilityClass - AnnaDev (@LynnBroe)
  • #4538: [java] Fix #4456: A false positive about FinalFieldCouldBeStatic and UtilityClass - AnnaDev (@LynnBroe)
  • #4540: [java] Fix #4457: false negative about OverrideBothEqualsAndHashcode - AnnaDev (@LynnBroe)
  • #4541: [java] Fix #4458: A false positive about RedundantFieldInitializer and @Value - AnnaDev (@LynnBroe)
  • #4542: [java] Fix #4510: A false positive about ConstructorCallsOverridableMethod and @Value - AnnaDev (@LynnBroe)
  • #4553: [java] Fix #4492: GuardLogStatement gives false positive when argument is a Java method reference - Anastasiia Koba (@anastasiia-koba)

🚀 Major Features and Enhancements

New official logo

The new official logo of PMD:

New PMD Logo

Revamped Java module

  • Java grammar substantially refactored - more correct regarding the Java Language Specification (JLS)
  • Built-in rules have been upgraded for the changed AST
  • Rewritten type resolution framework and symbol table correctly implements the JLS
  • AST exposes more semantic information (method calls, field accesses)

For more information, see the Detailed Release Notes for PMD 7.

Contributors: Clément Fournier (@oowekyala), Andreas Dangel (@adangel), Juan Martín Sotuyo Dodero (@jsotuyod)

Revamped Command Line Interface

  • unified and consistent Command Line Interface for both Linux/Unix and Windows across our different utilities
  • single script pmd (pmd.bat for Windows) to launch the different utilities:
    • pmd check to run PMD rules and analyze a project
    • pmd cpd to run CPD (copy paste detector)
    • pmd designer to run the PMD Rule Designer
  • progress bar support for pmd check
  • shell completion

Demo

For more information, see the Detailed Release Notes for PMD 7.

Contributors: Juan Martín Sotuyo Dodero (@jsotuyod)

Full Antlr support

  • Antlr based grammars can now be used to build full-fledged PMD rules.
  • Previously, Antlr grammar could only be used for CPD
  • New supported languages: Swift and Kotlin

For more information, see the Detailed Release Notes for PMD 7.

Contributors: Lucas Soncini (@lsoncini), Matías Fraga (@matifraga), Tomás De Lucca (@tomidelucca)

Updated PMD Designer

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

New CPD report format cpdhtml-v2.xslt

Thanks to @mohan-chinnappan-n a new CPD report format has been added which features a data table. It uses an XSLT stylesheet to convert CPD’s XML format into HTML.

See the example report.

Note that this is just a concise listing of the highlight. For more information on the languages, see the Detailed Release Notes for PMD 7.

New: Swift support

  • use PMD to analyze Swift code with PMD rules
  • initially 4 built-in rules

Contributors: Lucas Soncini (@lsoncini), Matías Fraga (@matifraga), Tomás De Lucca (@tomidelucca)

New: Kotlin support (experimental)

  • use PMD to analyze Kotlin code with PMD rules
  • Support for Kotlin 1.8 grammar
  • initially 2 built-in rules

New: CPD support for TypeScript

Thanks to a contribution, CPD now supports the TypeScript language. It is shipped with the rest of the JavaScript support in the module pmd-javascript.

Contributors: Paul Guyot (@pguyot)

New: CPD support for Julia

Thanks to a contribution, CPD now supports the Julia language. It is shipped in the new module pmd-julia.

Contributors: Wener (@wener-tiobe)

New: CPD support for Coco

Thanks to a contribution, CPD now supports Coco, a modern programming language designed specifically for building event-driven software. It is shipped in the new module pmd-coco.

Contributors: Wener (@wener-tiobe)

Changed: JavaScript support

  • latest version supports ES6 and also some new constructs (see Rhino])
  • comments are retained

Changed: Language versions

  • more predefined language versions for each supported language
  • can be used to limit rule execution for specific versions only with minimumLanguageVersion and maximumLanguageVersion attributes.

Changed: CPP can now ignore identifiers in sequences (CPD)

  • new command line option for CPD: --ignore-sequences.
  • This option is used for CPP only: with the already existing option --ignore-literal-sequences, only literals were ignored. The new option additional ignores identifiers as well in sequences.
  • See PR #4470 for details.

🌟 New and changed rules

New Rules

Apex

Java

  • UnnecessaryBoxing reports boxing and unboxing conversions that may be made implicit.

Kotlin

Swift

Changed Rules

General changes

Apex General changes

  • The properties cc_categories, cc_remediation_points_multiplier, cc_block_highlighting have been removed from all rules. These properties have been deprecated since PMD 6.13.0. See issue #1648 for more details.

Java General changes

  • Violations reported on methods or classes previously reported the line range of the entire method or class. With PMD 7.0.0, the reported location is now just the identifier of the method or class. This affects various rules, e.g. CognitiveComplexity.

    The report location is controlled by the overrides of the method getReportLocation in different node types.

    See issue #4439 and issue #730 for more details.

Java Best Practices

  • ArrayIsStoredDirectly: Violations are now reported on the assignment and not anymore on the formal parameter. The reported line numbers will probably move.
  • AvoidReassigningLoopVariables: This rule might not report anymore all reassignments of the control variable in for-loops when the property forReassign is set to skip. See issue #4500 for more details.
  • LooseCoupling: The rule has a new property to allow some types to be coupled to (allowedTypes).
  • UnusedLocalVariable: This rule has some important false-negatives fixed and finds many more cases now. For details see issues #2130, #4516, and #4517.

Java Codestyle

  • MethodNamingConventions: The property checkNativeMethods has been removed. The property was deprecated since PMD 6.3.0. Use the property nativePattern to control whether native methods should be considered or not.
  • ShortVariable: This rule now also reports short enum constant names.
  • UseDiamondOperator: The property java7Compatibility has been removed. The rule now handles Java 7 properly without a property.
  • UnnecessaryFullyQualifiedName: The rule has two new properties, to selectively disable reporting on static field and method qualifiers. The rule also has been improved to be more precise.
  • UselessParentheses: The rule has two new properties which control how strict the rule should be applied. With ignoreClarifying (default: true) parentheses that are strictly speaking not necessary are allowed, if they separate expressions of different precedence. The other property ignoreBalancing (default: true) is similar, in that it allows parentheses that help reading and understanding the expressions.

Java Design

  • CyclomaticComplexity: The property reportLevel has been removed. The property was deprecated since PMD 6.0.0. The report level can now be configured separated for classes and methods using classReportLevel and methodReportLevel instead.
  • ImmutableField: The property ignoredAnnotations has been removed. The property was deprecated since PMD 6.52.0.
  • LawOfDemeter: The rule has a new property trustRadius. This defines the maximum degree of trusted data. The default of 1 is the most restrictive.
  • NPathComplexity: The property minimum has been removed. It was deprecated since PMD 6.0.0. Use the property reportLevel instead.
  • SingularField: The properties checkInnerClasses and disallowNotAssignment have been removed. The rule is now more precise and will check these cases properly.
  • UseUtilityClass: The property ignoredAnnotations has been removed.

Java Documentation

  • CommentContent: The properties caseSensitive and disallowedTerms are removed. The new property forbiddenRegex can be used now to define the disallowed terms with a single regular expression.
  • CommentRequired:
    • Overridden methods are now detected even without the @Override annotation. This is relevant for the property methodWithOverrideCommentRequirement. See also pull request #3757.
    • Elements in annotation types are now detected as well. This might lead to an increased number of violations for missing public method comments.
  • CommentSize: When determining the line-length of a comment, the leading comment prefix markers (e.g. * or //) are ignored and don’t add up to the line-length. See also pull request #4369.

Java Error Prone

  • AvoidDuplicateLiterals: The property exceptionfile has been removed. The property was deprecated since PMD 6.10.0. Use the property exceptionList instead.
  • DontImportSun: sun.misc.Signal is not special-cased anymore.
  • EmptyCatchBlock: CloneNotSupportedException and InterruptedException are not special-cased anymore. Rename the exception parameter to ignored to ignore them.
  • ImplicitSwitchFallThrough: Violations are now reported on the case statements rather than on the switch statements. This is more accurate but might result in more violations now.

Removed Rules

Many rules, that were previously deprecated have been finally removed. See Detailed Release Notes for PMD 7 for the complete list.

🚨 API

The API of PMD has been growing over the years and needed some cleanup. The goal is, to have a clear separation between a well-defined API and the implementation, which is internal. This should help us in future development.

Also, there are some improvement and changes in different areas. For the detailed description of the changes listed here, see Detailed Release Notes for PMD 7.

  • Miscellaneous smaller changes and cleanups
  • XPath 3.1 support for XPath-based rules
  • Node stream API for AST traversal
  • Metrics framework
  • Testing framework
  • Language Lifecycle and Language Properties

💥 Compatibility and migration notes

See Detailed Release Notes for PMD 7.

🐛 Fixed Issues

  • miscellaneous
    • #881: [all] Breaking API changes for 7.0.0
    • #896: [all] Use slf4j
    • #1431: [ui] Remove old GUI applications (designerold, bgastviewer)
    • #1451: [core] RulesetFactoryCompatibility stores the whole ruleset file in memory as a string
    • #2496: Update PMD 7 Logo on landing page
    • #2497: PMD 7 Logo page
    • #2498: Update PMD 7 Logo in documentation
    • #3797: [all] Use JUnit5
    • #4462: Provide Software Bill of Materials (SBOM)
    • #4460: Fix assembly-plugin warnings
  • ant
    • #4080: [ant] Split off Ant integration into a new submodule
  • core
    • #880: [core] Make visitors generic
    • #1622: [core] NodeStream API
    • #1687: [core] Deprecate and Remove XPath 1.0 support
    • #1785: [core] Allow abstract node types to be valid rulechain visits
    • #1825: [core] Support NoAttribute for XPath
    • #2038: [core] Remove DCD
    • #2218: [core] isFindBoundary should not be an attribute
    • #2234: [core] Consolidate PMD CLI into a single command
    • #2239: [core] Merging Javacc build scripts
    • #2500: [core] Clarify API for ANTLR based languages
    • #2518: [core] Language properties
    • #2602: [core] Remove ParserOptions
    • #2614: [core] Upgrade Saxon, add XPath 3.1, remove Jaxen
    • #2696: [core] Remove DFA
    • #2821: [core] Rule processing error filenames are missing paths
    • #2873: [core] Utility classes in pmd 7
    • #2885: [core] Error recovery mode
    • #3203: [core] Replace RuleViolationFactory implementations with ViolationDecorator
    • #3692: [core] Analysis listeners
    • #3782: [core] Language lifecycle
    • #3815: [core] Update Saxon HE to 10.7
    • #3893: [core] Text documents
    • #3902: [core] Violation decorators
    • #3918: [core] Make LanguageRegistry non static
    • #3922: [core] Better error reporting for the ruleset parser
    • #4035: [core] ConcurrentModificationException in DefaultRuleViolationFactory
    • #4120: [core] Explicitly name all language versions
    • #4353: [core] Micro optimizations for Node API
    • #4365: [core] Improve benchmarking
    • #4420: [core] Remove PMD.EOL
    • #4425: [core] Replace TextFile::pathId
    • #4454: [core] “Unknown option: ‘-min’” but is referenced in documentation
  • cli
    • #2234: [core] Consolidate PMD CLI into a single command
    • #3828: [core] Progress reporting
    • #4079: [cli] Split off CLI implementation into a pmd-cli submodule
    • #4482: [cli] pmd.bat can only be executed once
    • #4484: [cli] ast-dump with no properties produce an NPE
  • doc
    • #2501: [doc] Verify ANTLR Documentation
    • #4438: [doc] Documentation links in VS Code are outdated
  • testing
    • #2435: [test] Remove duplicated Dummy language module
    • #4234: [test] Tests that change the logging level do not work

Language specific fixes:

  • apex
    • #1937: [apex] Apex should only have a single RootNode
    • #1648: [apex,vf] Remove CodeClimate dependency
    • #1750: [apex] Remove apex statistical rules
    • #2836: [apex] Remove Apex ProjectMirror
    • #4427: [apex] ApexBadCrypto test failing to detect inline code
  • apex-design
    • #2667: [apex] Integrate nawforce/ApexLink to build robust Unused rule
    • #4509: [apex] ExcessivePublicCount doesn’t consider inner classes correctly
  • java
    • #520: [java] Allow @SuppressWarnings with constants instead of literals
    • #864: [java] Similar/duplicated implementations for determining FQCN
    • #905: [java] Add new node for anonymous class declaration
    • #910: [java] AST inconsistency between primitive and reference type arrays
    • #997: [java] Java8 parsing corner case with annotated array types
    • #998: [java] AST inconsistencies around FormalParameter
    • #1019: [java] Breaking Java Grammar changes for PMD 7.0.0
    • #1124: [java] ImmutableList implementation in the qname codebase
    • #1128: [java] Improve ASTLocalVariableDeclaration
    • #1150: [java] ClassOrInterfaceType AST improvements
    • #1207: [java] Resolve explicit types using FQCNs, without hitting the classloader
    • #1367: [java] Parsing error on annotated inner class
    • #1661: [java] About operator nodes
    • #2366: [java] Remove qualified names
    • #2819: [java] GLB bugs in pmd 7
    • #3642: [java] Parse error on rare extra dimensions on method return type on annotation methods
    • #3763: [java] Ambiguous reference error in valid code
    • #3749: [java] Improve isOverridden in ASTMethodDeclaration
    • #3750: [java] Make symbol table support instanceof pattern bindings
    • #3752: [java] Expose annotations in symbol API
    • #4237: [java] Cleanup handling of Java comments
    • #4317: [java] Some AST nodes should not be TypeNodes
    • #4359: [java] Type resolution fails with NPE when the scope is not a type declaration
    • #4367: [java] Move testrule TypeResTest into internal
    • #4383: [java] IllegalStateException: Object is not an array type!
    • #4405: [java] Processing error with ArrayIndexOutOfBoundsException
  • java-bestpractices
    • #342: [java] AccessorMethodGeneration: Name clash with another public field not properly handled
    • #755: [java] AccessorClassGeneration false positive for private constructors
    • #770: [java] UnusedPrivateMethod yields false positive for counter-variant arguments
    • #807: [java] AccessorMethodGeneration false positive with overloads
    • #833: [java] ForLoopCanBeForeach should consider iterating on this
    • #1189: [java] UnusedPrivateMethod false positive from inner class via external class
    • #1205: [java] Improve ConstantsInInterface message to mention alternatives
    • #1212: [java] Don’t raise JUnitTestContainsTooManyAsserts on JUnit 5’s assertAll
    • #1422: [java] JUnitTestsShouldIncludeAssert false positive with inherited @Rule field
    • #1455: [java] JUnitTestsShouldIncludeAssert: False positives for assert methods named “check” and “verify”
    • #1563: [java] ForLoopCanBeForeach false positive with method call using index variable
    • #1565: [java] JUnitAssertionsShouldIncludeMessage false positive with AssertJ
    • #1747: [java] PreserveStackTrace false-positive
    • #1969: [java] MissingOverride false-positive triggered by package-private method overwritten in another package by extending class
    • #1998: [java] AccessorClassGeneration false-negative: subclass calls private constructor
    • #2130: [java] UnusedLocalVariable: false-negative with array
    • #2147: [java] JUnitTestsShouldIncludeAssert - false positives with lambdas and static methods
    • #2464: [java] LooseCoupling must ignore class literals: ArrayList.class
    • #2542: [java] UseCollectionIsEmpty can not detect the case foo.bar().size()
    • #2650: [java] UseTryWithResources false positive when AutoCloseable helper used
    • #2796: [java] UnusedAssignment false positive with call chains
    • #2797: [java] MissingOverride long-standing issues
    • #2806: [java] SwitchStmtsShouldHaveDefault false-positive with Java 14 switch non-fallthrough branches
    • #2822: [java] LooseCoupling rule: Extend to cover user defined implementations and interfaces
    • #2843: [java] Fix UnusedAssignment FP with field accesses
    • #2882: [java] UseTryWithResources - false negative for explicit close
    • #2883: [java] JUnitAssertionsShouldIncludeMessage false positive with method call
    • #2890: [java] UnusedPrivateMethod false positive with generics
    • #2946: [java] SwitchStmtsShouldHaveDefault false positive on enum inside enums
    • #3672: [java] LooseCoupling - fix false positive with generics
    • #3675: [java] MissingOverride - fix false positive with mixing type vars
    • #3858: [java] UseCollectionIsEmpty should infer local variable type from method invocation
    • #4433: [java] [7.0-rc1] ReplaceHashtableWithMap on java.util.Properties
    • #4492: [java] GuardLogStatement gives false positive when argument is a Java method reference
    • #4503: [java] JUnitTestsShouldIncludeAssert: false negative with TestNG
    • #4516: [java] UnusedLocalVariable: false-negative with try-with-resources
    • #4517: [java] UnusedLocalVariable: false-negative with compound assignments
    • #4518: [java] UnusedLocalVariable: false-positive with multiple for-loop indices
  • java-codestyle
    • #1208: [java] PrematureDeclaration rule false-positive on variable declared to measure time
    • #1429: [java] PrematureDeclaration as result of method call (false positive)
    • #1480: [java] IdenticalCatchBranches false positive with return expressions
    • #1673: [java] UselessParentheses false positive with conditional operator
    • #1790: [java] UnnecessaryFullyQualifiedName false positive with enum constant
    • #1918: [java] UselessParentheses false positive with boolean operators
    • #2134: [java] PreserveStackTrace not handling Throwable.addSuppressed(...)
    • #2299: [java] UnnecessaryFullyQualifiedName false positive with similar package name
    • #2391: [java] UseDiamondOperator FP when expected type and constructed type have a different parameterization
    • #2528: [java] MethodNamingConventions - JUnit 5 method naming not support ParameterizedTest
    • #2739: [java] UselessParentheses false positive for string concatenation
    • #2748: [java] UnnecessaryCast false positive with unchecked cast
    • #2973: [java] New rule: UnnecessaryBoxing
    • #3195: [java] Improve rule UnnecessaryReturn to detect more cases
    • #3218: [java] Generalize UnnecessaryCast to flag all unnecessary casts
    • #3221: [java] PrematureDeclaration false positive for unused variables
    • #3238: [java] Improve ExprContext, fix FNs of UnnecessaryCast
    • #3500: [java] UnnecessaryBoxing - check for Integer.valueOf(String) calls
    • #4268: [java] CommentDefaultAccessModifier: false positive with TestNG annotations
    • #4273: [java] CommentDefaultAccessModifier ignoredAnnotations should include “org.junit.jupiter.api.extension.RegisterExtension” by default
    • #4357: [java] Fix IllegalStateException in UseDiamondOperator rule
    • #4432: [java] [7.0-rc1] UnnecessaryImport - Unused static import is being used
    • #4455: [java] FieldNamingConventions: false positive with lombok’s @UtilityClass
    • #4487: [java] UnnecessaryConstructor: false-positive with @Inject and @Autowired
    • #4511: [java] LocalVariableCouldBeFinal shouldn’t report unused variables
    • #4512: [java] MethodArgumentCouldBeFinal shouldn’t report unused parameters
    • #4557: [java] UnnecessaryImport FP with static imports of overloaded methods
  • java-design
    • #1014: [java] LawOfDemeter: False positive with lambda expression
    • #1605: [java] LawOfDemeter: False positive for standard UTF-8 charset name
    • #2160: [java] Issues with Law of Demeter
    • #2175: [java] LawOfDemeter: False positive for chained methods with generic method call
    • #2179: [java] LawOfDemeter: False positive with static property access - should treat class-level property as global object, not dot-accessed property
    • #2180: [java] LawOfDemeter: False positive with Thread and ThreadLocalRandom
    • #2182: [java] LawOfDemeter: False positive with package-private access
    • #2188: [java] LawOfDemeter: False positive with fields assigned to local vars
    • #2536: [java] ClassWithOnlyPrivateConstructorsShouldBeFinal can’t detect inner class
    • #3668: [java] ClassWithOnlyPrivateConstructorsShouldBeFinal - fix FP with inner private classes
    • #3754: [java] SingularField false positive with read in while condition
    • #3786: [java] SimplifyBooleanReturns should consider operator precedence
    • #3840: [java] LawOfDemeter disallows method call on locally created object
    • #4238: [java] Make LawOfDemeter not use the rulechain
    • #4254: [java] ImmutableField - false positive with Lombok @Setter
    • #4434: [java] [7.0-rc1] ExceptionAsFlowControl when simply propagating
    • #4456: [java] FinalFieldCouldBeStatic: false positive with lombok’s @UtilityClass
    • #4477: [java] SignatureDeclareThrowsException: false-positive with TestNG annotations
    • #4490: [java] ImmutableField - false negative with Lombok @Getter
    • #4549: [java] Make LawOfDemeter results deterministic
  • java-documentation
    • #4369: [java] Improve CommentSize
    • #4416: [java] Fix reported line number in CommentContentRule
  • java-errorprone
    • #659: [java] MissingBreakInSwitch - last default case does not contain a break
    • #1005: [java] CloneMethodMustImplementCloneable triggers for interfaces
    • #1669: [java] NullAssignment - FP with ternay and null as constructor argument
    • #1899: [java] Recognize @SuppressWanings(“fallthrough”) for MissingBreakInSwitch
    • #2320: [java] NullAssignment - FP with ternary and null as method argument
    • #2532: [java] AvoidDecimalLiteralsInBigDecimalConstructor can not detect the case new BigDecimal(Expression)
    • #2579: [java] MissingBreakInSwitch detects the lack of break in the last case
    • #2880: [java] CompareObjectsWithEquals - false negative with type res
    • #2893: [java] Remove special cases from rule EmptyCatchBlock
    • #2894: [java] Improve MissingBreakInSwitch
    • #3071: [java] BrokenNullCheck FP with PMD 6.30.0
    • #3087: [java] UnnecessaryBooleanAssertion overlaps with SimplifiableTestAssertion
    • #3100: [java] UseCorrectExceptionLogging FP in 6.31.0
    • #3173: [java] UseProperClassLoader false positive
    • #3351: [java] ConstructorCallsOverridableMethod ignores abstract methods
    • #3400: [java] AvoidUsingOctalValues FN with underscores
    • #3843: [java] UseEqualsToCompareStrings should consider return type
    • #4063: [java] AvoidBranchingStatementAsLastInLoop: False-negative about try/finally block
    • #4356: [java] Fix NPE in CloseResourceRule
    • #4449: [java] AvoidAccessibilityAlteration: Possible false positive in AvoidAccessibilityAlteration rule when using Lambda expression
    • #4457: [java] OverrideBothEqualsAndHashcode: false negative with anonymous classes
    • #4493: [java] MissingStaticMethodInNonInstantiatableClass: false-positive about @Inject
    • #4505: [java] ImplicitSwitchFallThrough NPE in PMD 7.0.0-rc1
    • #4510: [java] ConstructorCallsOverridableMethod: false positive with lombok’s @Value
    • #4513: [java] UselessOperationOnImmutable various false negatives with String
    • #4514: [java] AvoidLiteralsInIfCondition false positive and negative for String literals when ignoreExpressions=true
    • #4546: [java] OverrideBothEqualsAndHashCode ignores records
  • java-multithreading
    • #2537: [java] DontCallThreadRun can’t detect the case that call run() in this.run()
    • #2538: [java] DontCallThreadRun can’t detect the case that call run() in foo.bar.run()
    • #2577: [java] UseNotifyAllInsteadOfNotify falsely detect a special case with argument: foo.notify(bar)
    • #4483: [java] NonThreadSafeSingleton false positive with double-checked locking
  • java-performance
    • #1224: [java] InefficientEmptyStringCheck false negative in anonymous class
    • #2587: [java] AvoidArrayLoops could also check for list copy through iterated List.add()
    • #2712: [java] SimplifyStartsWith false-positive with AssertJ
    • #3486: [java] InsufficientStringBufferDeclaration: Fix NPE
    • #3848: [java] StringInstantiation: false negative when using method result
    • #4070: [java] A false positive about the rule RedundantFieldInitializer
    • #4458: [java] RedundantFieldInitializer: false positive with lombok’s @Value
  • kotlin
    • #419: [kotlin] Add support for Kotlin
    • #4389: [kotlin] Update grammar to version 1.8
  • swift
    • #1877: [swift] Feature/swift rules
    • #1882: [swift] UnavailableFunction Swift rule
  • xml
    • #1800: [xml] Unimplement org.w3c.dom.Node from the XmlNodeWrapper

✨ External Contributions

  • #1658: [core] Node support for Antlr-based languages - Matías Fraga (@matifraga)
  • #1698: [core] [swift] Antlr Base Parser adapter and Swift Implementation - Lucas Soncini (@lsoncini)
  • #1774: [core] Antlr visitor rules - Lucas Soncini (@lsoncini)
  • #1877: [swift] Feature/swift rules - Matías Fraga (@matifraga)
  • #1881: [doc] Add ANTLR documentation - Matías Fraga (@matifraga)
  • #1882: [swift] UnavailableFunction Swift rule - Tomás de Lucca (@tomidelucca)
  • #2830: [apex] Apexlink POC - Kevin Jones (@nawforce)
  • #3866: [core] Add CLI Progress Bar - @JerritEic (@JerritEic)
  • #4402: [javascript] CPD: add support for Typescript using antlr4 grammar - Paul Guyot (@pguyot)
  • #4403: [julia] CPD: Add support for Julia code duplication - Wener (@wener-tiobe)
  • #4412: [doc] Added new error msg to ConstantsInInterface - David Ljunggren (@dague1)
  • #4426: [cpd] New XML to HTML XLST report format for PMD CPD - mohan-chinnappan-n (@mohan-chinnappan-n)
  • #4428: [apex] ApexBadCrypto bug fix for #4427 - inline detection of hard coded values - Steven Stearns (@sfdcsteve)
  • #4431: [coco] CPD: Coco support for code duplication detection - Wener (@wener-tiobe)
  • #4444: [java] CommentDefaultAccessModifier - ignore org.junit.jupiter.api.extension.RegisterExtension by default - Nirvik Patel (@nirvikpatel)
  • #4450: [java] Fix #4449 AvoidAccessibilityAlteration: Correctly handle Lambda expressions in PrivilegedAction scenarios - Seren (@mohui1999)
  • #4452: [doc] Update PMD_APEX_ROOT_DIRECTORY documentation reference - nwcm (@nwcm)
  • #4470: [cpp] CPD: Added strings as literal and ignore identifiers in sequences - Wener (@wener-tiobe)
  • #4474: [java] ImmutableField: False positive with lombok (fixes #4254) - Pim van der Loos (@PimvanderLoos)
  • #4488: [java] Fix #4477: A false-positive about SignatureDeclareThrowsException - AnnaDev (@LynnBroe)
  • #4494: [java] Fix #4487: A false-positive about UnnecessaryConstructor and @Inject and @Autowired - AnnaDev (@LynnBroe)
  • #4495: [java] Fix #4493: false-positive about MissingStaticMethodInNonInstantiatableClass and @Inject - AnnaDev (@LynnBroe)
  • #4507: [java] Fix #4503: A false negative about JUnitTestsShouldIncludeAssert and testng - AnnaDev (@LynnBroe)
  • #4520: [doc] Fix typo: missing closing quotation mark after CPD-END - João Dinis Ferreira (@joaodinissf)
  • #4533: [java] Fix #4063: False-negative about try/catch block in Loop - AnnaDev (@LynnBroe)
  • #4536: [java] Fix #4268: CommentDefaultAccessModifier - false positive with TestNG’s @Test annotation - AnnaDev (@LynnBroe)
  • #4537: [java] Fix #4455: A false positive about FieldNamingConventions and UtilityClass - AnnaDev (@LynnBroe)
  • #4538: [java] Fix #4456: A false positive about FinalFieldCouldBeStatic and UtilityClass - AnnaDev (@LynnBroe)
  • #4540: [java] Fix #4457: false negative about OverrideBothEqualsAndHashcode - AnnaDev (@LynnBroe)
  • #4541: [java] Fix #4458: A false positive about RedundantFieldInitializer and @Value - AnnaDev (@LynnBroe)
  • #4542: [java] Fix #4510: A false positive about ConstructorCallsOverridableMethod and @Value - AnnaDev (@LynnBroe)
  • #4553: [java] Fix #4492: GuardLogStatement gives false positive when argument is a Java method reference - Anastasiia Koba (@anastasiia-koba)

📈 Stats

  • 4694 commits
  • 617 closed tickets & PRs
  • Days since last release: 30

29-April-2023 - 7.0.0-rc2

We’re excited to bring you the next major version of PMD!

Since this is a big release, we provide here only a concise version of the release notes. We prepared a separate page with the full Detailed Release Notes for PMD 7.0.0.

ℹ️ Release Candidates

PMD 7.0.0 is finally almost ready. In order to gather feedback, we are going to ship a couple of release candidates. These are officially available on GitHub and Maven Central and can be used as usual (e.g. as a dependency). We encourage you to try out the new features, but keep in mind that we may introduce API breaking changes between the release candidates. It should be stable enough if you don't use custom rules.

We have still some tasks planned for the next release candidates. You can see the progress in PMD 7 Tracking Issue #3898.

If you find any problem or difficulty while updating from PMD 6, please provide feedback via our issue tracker. That way we can improve the experience for all.

Table Of Contents

Changes since 7.0.0-rc1

This section lists the most important changes from the last release candidate. The remaining section describes the complete release notes for 7.0.0.

API Changes

  • Moved the two classes AntlrTokenizer and JavaCCTokenizer from internal package into package net.sourceforge.pmd.cpd.impl. These two classes are part of the API and are base classes for CPD language implementations.
  • AntlrBaseRule is gone in favor of AbstractVisitorRule.
  • The classes KotlinInnerNode and SwiftInnerNode are package-private now.
  • The parameter order of addSourceFile has been swapped in order to have the same meaning as in 6.55.0. That will make it easier if you upgrade from 6.55.0 to 7.0.0. However, that means, that you need to change these method calls if you have migrated to 7.0.0-rc1 already.

Updated PMD Designer

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

  • New: CPD support for TypeScript
  • New: CPD support for Julia

Rule Changes

  • ImmutableField: the property ignoredAnnotations has been removed. The property was deprecated since PMD 6.52.0.
  • SwitchDensity: the type of the property minimum has been changed from decimal to integer for consistency with other statistical rules.

Fixed Issues

  • cli
    • #4482: [cli] pmd.bat can only be executed once
    • #4484: [cli] ast-dump with no properties produce an NPE
  • core
    • #2500: [core] Clarify API for ANTLR based languages
  • doc
    • #2501: [doc] Verify ANTLR Documentation
    • #4438: [doc] Documentation links in VS Code are outdated
  • java-codestyle
    • #4273: [java] CommentDefaultAccessModifier ignoredAnnotations should include “org.junit.jupiter.api.extension.RegisterExtension” by default
    • #4487: [java] UnnecessaryConstructor: false-positive with @Inject and @Autowired
  • java-design
    • #4254: [java] ImmutableField - false positive with Lombok @Setter
    • #4477: [java] SignatureDeclareThrowsException: false-positive with TestNG annotations
    • #4490: [java] ImmutableField - false negative with Lombok @Getter
  • java-errorprone
    • #4449: [java] AvoidAccessibilityAlteration: Possible false positive in AvoidAccessibilityAlteration rule when using Lambda expression
    • #4493: [java] MissingStaticMethodInNonInstantiatableClass: false-positive about @Inject
    • #4505: [java] ImplicitSwitchFallThrough NPE in PMD 7.0.0-rc1
  • java-multithreading
    • #4483: [java] NonThreadSafeSingleton false positive with double-checked locking
  • miscellaneous
    • #4462: Provide Software Bill of Materials (SBOM)

External contributions

  • #4402: [javascript] CPD: add support for Typescript using antlr4 grammar - Paul Guyot (@pguyot)
  • #4403: [julia] CPD: Add support for Julia code duplication - Wener (@wener-tiobe)
  • #4444: [java] CommentDefaultAccessModifier - ignore org.junit.jupiter.api.extension.RegisterExtension by default - Nirvik Patel (@nirvikpatel)
  • #4450: [java] Fix #4449 AvoidAccessibilityAlteration: Correctly handle Lambda expressions in PrivilegedAction scenarios - Seren (@mohui1999)
  • #4452: [doc] Update PMD_APEX_ROOT_DIRECTORY documentation reference - nwcm (@nwcm)
  • #4474: [java] ImmutableField: False positive with lombok (fixes #4254) - Pim van der Loos (@PimvanderLoos)
  • #4488: [java] Fix #4477: A false-positive about SignatureDeclareThrowsException - AnnaDev (@LynnBroe)
  • #4494: [java] Fix #4487: A false-positive about UnnecessaryConstructor and @Inject and @Autowired - AnnaDev (@LynnBroe)
  • #4495: [java] Fix #4493: false-positive about MissingStaticMethodInNonInstantiatableClass and @Inject - AnnaDev (@LynnBroe)
  • #4520: [doc] Fix typo: missing closing quotation mark after CPD-END - João Dinis Ferreira (@joaodinissf)

🚀 Major Features and Enhancements

New official logo

The new official logo of PMD:

New PMD Logo

Revamped Java module

  • Java grammar substantially refactored - more correct regarding the Java Language Specification (JLS)
  • Built-in rules have been upgraded for the changed AST
  • Rewritten type resolution framework and symbol table correctly implements the JLS
  • AST exposes more semantic information (method calls, field accesses)

For more information, see the Detailed Release Notes for PMD 7.

Contributors: Clément Fournier (@oowekyala), Andreas Dangel (@adangel), Juan Martín Sotuyo Dodero (@jsotuyod)

Revamped Command Line Interface

  • unified and consistent Command Line Interface for both Linux/Unix and Windows across our different utilities
  • single script pmd (pmd.bat for Windows) to launch the different utilities:
    • pmd check to run PMD rules and analyze a project
    • pmd cpd to run CPD (copy paste detector)
    • pmd designer to run the PMD Rule Designer
  • progress bar support for pmd check
  • shell completion

Demo

For more information, see the Detailed Release Notes for PMD 7.

Contributors: Juan Martín Sotuyo Dodero (@jsotuyod)

Full Antlr support

  • Antlr based grammars can now be used to build full-fledged PMD rules.
  • Previously, Antlr grammar could only be used for CPD
  • New supported languages: Swift and Kotlin

For more information, see the Detailed Release Notes for PMD 7.

Contributors: Lucas Soncini (@lsoncini), Matías Fraga (@matifraga), Tomás De Lucca (@tomidelucca)

Updated PMD Designer

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

Note that this is just a concise listing of the highlight. For more information on the languages, see the Detailed Release Notes for PMD 7.

New: Swift support

  • use PMD to analyze Swift code with PMD rules
  • initially 4 built-in rules

Contributors: Lucas Soncini (@lsoncini), Matías Fraga (@matifraga), Tomás De Lucca (@tomidelucca)

New: Kotlin support (experimental)

  • use PMD to analyze Kotlin code with PMD rules
  • Support for Kotlin 1.8 grammar
  • initially 2 built-in rules

New: CPD support for TypeScript

Thanks to a contribution, CPD now supports the TypeScript language. It is shipped with the rest of the JavaScript support in the module pmd-javascript.

Contributors: Paul Guyot (@pguyot)

New: CPD support for Julia

Thanks to a contribution, CPD now supports the Julia language. It is shipped in the new module pmd-julia.

Contributors: Wener (@wener-tiobe)

Changed: JavaScript support

  • latest version supports ES6 and also some new constructs (see Rhino])
  • comments are retained

Changed: Language versions

  • more predefined language versions for each supported language
  • can be used to limit rule execution for specific versions only with minimumLanguageVersion and maximumLanguageVersion attributes.

🌟 New and changed rules

New Rules

Apex

Java

  • UnnecessaryBoxing reports boxing and unboxing conversions that may be made implicit.

Kotlin

Swift

Changed Rules

General changes

Apex General changes

  • The properties cc_categories, cc_remediation_points_multiplier, cc_block_highlighting have been removed from all rules. These properties have been deprecated since PMD 6.13.0. See issue #1648 for more details.

Java General changes

  • Violations reported on methods or classes previously reported the line range of the entire method or class. With PMD 7.0.0, the reported location is now just the identifier of the method or class. This affects various rules, e.g. CognitiveComplexity.

    The report location is controlled by the overrides of the method getReportLocation in different node types.

    See issue #4439 and issue #730 for more details.

Java Best Practices

  • ArrayIsStoredDirectly: Violations are now reported on the assignment and not anymore on the formal parameter. The reported line numbers will probably move.
  • AvoidReassigningLoopVariables: This rule might not report anymore all reassignments of the control variable in for-loops when the property forReassign is set to skip. See issue #4500 for more details.
  • LooseCoupling: The rule has a new property to allow some types to be coupled to (allowedTypes).
  • UnusedLocalVariable: This rule has some important false-negatives fixed and finds many more cases now. For details see issues #2130, #4516, and #4517.

Java Codestyle

  • MethodNamingConventions: The property checkNativeMethods has been removed. The property was deprecated since PMD 6.3.0. Use the property nativePattern to control whether native methods should be considered or not.
  • ShortVariable: This rule now also reports short enum constant names.
  • UseDiamondOperator: The property java7Compatibility has been removed. The rule now handles Java 7 properly without a property.
  • UnnecessaryFullyQualifiedName: The rule has two new properties, to selectively disable reporting on static field and method qualifiers. The rule also has been improved to be more precise.
  • UselessParentheses: The rule has two new properties which control how strict the rule should be applied. With ignoreClarifying (default: true) parentheses that are strictly speaking not necessary are allowed, if they separate expressions of different precedence. The other property ignoreBalancing (default: true) is similar, in that it allows parentheses that help reading and understanding the expressions.

Java Design

  • CyclomaticComplexity: The property reportLevel has been removed. The property was deprecated since PMD 6.0.0. The report level can now be configured separated for classes and methods using classReportLevel and methodReportLevel instead.
  • ImmutableField: The property ignoredAnnotations has been removed. The property was deprecated since PMD 6.52.0.
  • LawOfDemeter: The rule has a new property trustRadius. This defines the maximum degree of trusted data. The default of 1 is the most restrictive.
  • NPathComplexity: The property minimum has been removed. It was deprecated since PMD 6.0.0. Use the property reportLevel instead.
  • SingularField: The properties checkInnerClasses and disallowNotAssignment have been removed. The rule is now more precise and will check these cases properly.
  • UseUtilityClass: The property ignoredAnnotations has been removed.

Java Documentation

  • CommentContent: The properties caseSensitive and disallowedTerms are removed. The new property forbiddenRegex can be used now to define the disallowed terms with a single regular expression.
  • CommentRequired:
    • Overridden methods are now detected even without the @Override annotation. This is relevant for the property methodWithOverrideCommentRequirement. See also pull request #3757.
    • Elements in annotation types are now detected as well. This might lead to an increased number of violations for missing public method comments.
  • CommentSize: When determining the line-length of a comment, the leading comment prefix markers (e.g. * or //) are ignored and don’t add up to the line-length. See also pull request #4369.

Java Error Prone

  • AvoidDuplicateLiterals: The property exceptionfile has been removed. The property was deprecated since PMD 6.10.0. Use the property exceptionList instead.
  • DontImportSun: sun.misc.Signal is not special-cased anymore.
  • EmptyCatchBlock: CloneNotSupportedException and InterruptedException are not special-cased anymore. Rename the exception parameter to ignored to ignore them.
  • ImplicitSwitchFallThrough: Violations are now reported on the case statements rather than on the switch statements. This is more accurate but might result in more violations now.

Removed Rules

Many rules, that were previously deprecated have been finally removed. See Detailed Release Notes for PMD 7 for the complete list.

🚨 API

The API of PMD has been growing over the years and needed some cleanup. The goal is, to have a clear separation between a well-defined API and the implementation, which is internal. This should help us in future development.

Also, there are some improvement and changes in different areas. For the detailed description of the changes listed here, see Detailed Release Notes for PMD 7.

  • Miscellaneous smaller changes and cleanups
  • XPath 3.1 support for XPath-based rules
  • Node stream API for AST traversal
  • Metrics framework
  • Testing framework
  • Language Lifecycle and Language Properties

💥 Compatibility and migration notes

See Detailed Release Notes for PMD 7.

🐛 Fixed Issues

  • miscellaneous
    • #881: [all] Breaking API changes for 7.0.0
    • #896: [all] Use slf4j
    • #1431: [ui] Remove old GUI applications (designerold, bgastviewer)
    • #1451: [core] RulesetFactoryCompatibility stores the whole ruleset file in memory as a string
    • #2496: Update PMD 7 Logo on landing page
    • #2497: PMD 7 Logo page
    • #2498: Update PMD 7 Logo in documentation
    • #3797: [all] Use JUnit5
    • #4462: Provide Software Bill of Materials (SBOM)
  • ant
    • #4080: [ant] Split off Ant integration into a new submodule
  • core
    • #880: [core] Make visitors generic
    • #1622: [core] NodeStream API
    • #1687: [core] Deprecate and Remove XPath 1.0 support
    • #1785: [core] Allow abstract node types to be valid rulechain visits
    • #1825: [core] Support NoAttribute for XPath
    • #2038: [core] Remove DCD
    • #2218: [core] isFindBoundary should not be an attribute
    • #2234: [core] Consolidate PMD CLI into a single command
    • #2239: [core] Merging Javacc build scripts
    • #2500: [core] Clarify API for ANTLR based languages
    • #2518: [core] Language properties
    • #2602: [core] Remove ParserOptions
    • #2614: [core] Upgrade Saxon, add XPath 3.1, remove Jaxen
    • #2696: [core] Remove DFA
    • #2821: [core] Rule processing error filenames are missing paths
    • #2873: [core] Utility classes in pmd 7
    • #2885: [core] Error recovery mode
    • #3203: [core] Replace RuleViolationFactory implementations with ViolationDecorator
    • #3692: [core] Analysis listeners
    • #3782: [core] Language lifecycle
    • #3815: [core] Update Saxon HE to 10.7
    • #3893: [core] Text documents
    • #3902: [core] Violation decorators
    • #3918: [core] Make LanguageRegistry non static
    • #3922: [core] Better error reporting for the ruleset parser
    • #4035: [core] ConcurrentModificationException in DefaultRuleViolationFactory
    • #4120: [core] Explicitly name all language versions
    • #4353: [core] Micro optimizations for Node API
    • #4365: [core] Improve benchmarking
    • #4420: [core] Remove PMD.EOL
  • cli
    • #2234: [core] Consolidate PMD CLI into a single command
    • #3828: [core] Progress reporting
    • #4079: [cli] Split off CLI implementation into a pmd-cli submodule
    • #4482: [cli] pmd.bat can only be executed once
    • #4484: [cli] ast-dump with no properties produce an NPE
  • doc
    • #2501: [doc] Verify ANTLR Documentation
    • #4438: [doc] Documentation links in VS Code are outdated
  • testing
    • #2435: [test] Remove duplicated Dummy language module
    • #4234: [test] Tests that change the logging level do not work

Language specific fixes:

  • apex
    • #1937: [apex] Apex should only have a single RootNode
    • #1648: [apex,vf] Remove CodeClimate dependency
    • #1750: [apex] Remove apex statistical rules
    • #2836: [apex] Remove Apex ProjectMirror
    • #4427: [apex] ApexBadCrypto test failing to detect inline code
  • apex-design
    • #2667: [apex] Integrate nawforce/ApexLink to build robust Unused rule
    • #4509: [apex] ExcessivePublicCount doesn’t consider inner classes correctly
  • java
    • #520: [java] Allow @SuppressWarnings with constants instead of literals
    • #864: [java] Similar/duplicated implementations for determining FQCN
    • #905: [java] Add new node for anonymous class declaration
    • #910: [java] AST inconsistency between primitive and reference type arrays
    • #997: [java] Java8 parsing corner case with annotated array types
    • #998: [java] AST inconsistencies around FormalParameter
    • #1019: [java] Breaking Java Grammar changes for PMD 7.0.0
    • #1124: [java] ImmutableList implementation in the qname codebase
    • #1128: [java] Improve ASTLocalVariableDeclaration
    • #1150: [java] ClassOrInterfaceType AST improvements
    • #1207: [java] Resolve explicit types using FQCNs, without hitting the classloader
    • #1367: [java] Parsing error on annotated inner class
    • #1661: [java] About operator nodes
    • #2366: [java] Remove qualified names
    • #2819: [java] GLB bugs in pmd 7
    • #3642: [java] Parse error on rare extra dimensions on method return type on annotation methods
    • #3763: [java] Ambiguous reference error in valid code
    • #3749: [java] Improve isOverridden in ASTMethodDeclaration
    • #3750: [java] Make symbol table support instanceof pattern bindings
    • #3752: [java] Expose annotations in symbol API
    • #4237: [java] Cleanup handling of Java comments
    • #4317: [java] Some AST nodes should not be TypeNodes
    • #4359: [java] Type resolution fails with NPE when the scope is not a type declaration
    • #4367: [java] Move testrule TypeResTest into internal
  • java-bestpractices
    • #342: [java] AccessorMethodGeneration: Name clash with another public field not properly handled
    • #755: [java] AccessorClassGeneration false positive for private constructors
    • #770: [java] UnusedPrivateMethod yields false positive for counter-variant arguments
    • #807: [java] AccessorMethodGeneration false positive with overloads
    • #833: [java] ForLoopCanBeForeach should consider iterating on this
    • #1189: [java] UnusedPrivateMethod false positive from inner class via external class
    • #1205: [java] Improve ConstantsInInterface message to mention alternatives
    • #1212: [java] Don’t raise JUnitTestContainsTooManyAsserts on JUnit 5’s assertAll
    • #1422: [java] JUnitTestsShouldIncludeAssert false positive with inherited @Rule field
    • #1455: [java] JUnitTestsShouldIncludeAssert: False positives for assert methods named “check” and “verify”
    • #1563: [java] ForLoopCanBeForeach false positive with method call using index variable
    • #1565: [java] JUnitAssertionsShouldIncludeMessage false positive with AssertJ
    • #1747: [java] PreserveStackTrace false-positive
    • #1969: [java] MissingOverride false-positive triggered by package-private method overwritten in another package by extending class
    • #1998: [java] AccessorClassGeneration false-negative: subclass calls private constructor
    • #2130: [java] UnusedLocalVariable: false-negative with array
    • #2147: [java] JUnitTestsShouldIncludeAssert - false positives with lambdas and static methods
    • #2464: [java] LooseCoupling must ignore class literals: ArrayList.class
    • #2542: [java] UseCollectionIsEmpty can not detect the case foo.bar().size()
    • #2650: [java] UseTryWithResources false positive when AutoCloseable helper used
    • #2796: [java] UnusedAssignment false positive with call chains
    • #2797: [java] MissingOverride long-standing issues
    • #2806: [java] SwitchStmtsShouldHaveDefault false-positive with Java 14 switch non-fallthrough branches
    • #2822: [java] LooseCoupling rule: Extend to cover user defined implementations and interfaces
    • #2843: [java] Fix UnusedAssignment FP with field accesses
    • #2882: [java] UseTryWithResources - false negative for explicit close
    • #2883: [java] JUnitAssertionsShouldIncludeMessage false positive with method call
    • #2890: [java] UnusedPrivateMethod false positive with generics
    • #2946: [java] SwitchStmtsShouldHaveDefault false positive on enum inside enums
    • #3672: [java] LooseCoupling - fix false positive with generics
    • #3675: [java] MissingOverride - fix false positive with mixing type vars
    • #3858: [java] UseCollectionIsEmpty should infer local variable type from method invocation
    • #4516: [java] UnusedLocalVariable: false-negative with try-with-resources
    • #4517: [java] UnusedLocalVariable: false-negative with compound assignments
    • #4518: [java] UnusedLocalVariable: false-positive with multiple for-loop indices
  • java-codestyle
    • #1208: [java] PrematureDeclaration rule false-positive on variable declared to measure time
    • #1429: [java] PrematureDeclaration as result of method call (false positive)
    • #1480: [java] IdenticalCatchBranches false positive with return expressions
    • #1673: [java] UselessParentheses false positive with conditional operator
    • #1790: [java] UnnecessaryFullyQualifiedName false positive with enum constant
    • #1918: [java] UselessParentheses false positive with boolean operators
    • #2134: [java] PreserveStackTrace not handling Throwable.addSuppressed(...)
    • #2299: [java] UnnecessaryFullyQualifiedName false positive with similar package name
    • #2391: [java] UseDiamondOperator FP when expected type and constructed type have a different parameterization
    • #2528: [java] MethodNamingConventions - JUnit 5 method naming not support ParameterizedTest
    • #2739: [java] UselessParentheses false positive for string concatenation
    • #2748: [java] UnnecessaryCast false positive with unchecked cast
    • #2973: [java] New rule: UnnecessaryBoxing
    • #3195: [java] Improve rule UnnecessaryReturn to detect more cases
    • #3218: [java] Generalize UnnecessaryCast to flag all unnecessary casts
    • #3221: [java] PrematureDeclaration false positive for unused variables
    • #3238: [java] Improve ExprContext, fix FNs of UnnecessaryCast
    • #3500: [java] UnnecessaryBoxing - check for Integer.valueOf(String) calls
    • #4273: [java] CommentDefaultAccessModifier ignoredAnnotations should include “org.junit.jupiter.api.extension.RegisterExtension” by default
    • #4357: [java] Fix IllegalStateException in UseDiamondOperator rule
    • #4487: [java] UnnecessaryConstructor: false-positive with @Inject and @Autowired
    • #4511: [java] LocalVariableCouldBeFinal shouldn’t report unused variables
    • #4512: [java] MethodArgumentCouldBeFinal shouldn’t report unused parameters
  • java-design
    • #1014: [java] LawOfDemeter: False positive with lambda expression
    • #1605: [java] LawOfDemeter: False positive for standard UTF-8 charset name
    • #2160: [java] Issues with Law of Demeter
    • #2175: [java] LawOfDemeter: False positive for chained methods with generic method call
    • #2179: [java] LawOfDemeter: False positive with static property access - should treat class-level property as global object, not dot-accessed property
    • #2180: [java] LawOfDemeter: False positive with Thread and ThreadLocalRandom
    • #2182: [java] LawOfDemeter: False positive with package-private access
    • #2188: [java] LawOfDemeter: False positive with fields assigned to local vars
    • #2536: [java] ClassWithOnlyPrivateConstructorsShouldBeFinal can’t detect inner class
    • #3668: [java] ClassWithOnlyPrivateConstructorsShouldBeFinal - fix FP with inner private classes
    • #3754: [java] SingularField false positive with read in while condition
    • #3786: [java] SimplifyBooleanReturns should consider operator precedence
    • #4238: [java] Make LawOfDemeter not use the rulechain
    • #4254: [java] ImmutableField - false positive with Lombok @Setter
    • #4477: [java] SignatureDeclareThrowsException: false-positive with TestNG annotations
    • #4490: [java] ImmutableField - false negative with Lombok @Getter
  • java-documentation
    • #4369: [java] Improve CommentSize
    • #4416: [java] Fix reported line number in CommentContentRule
  • java-errorprone
    • #659: [java] MissingBreakInSwitch - last default case does not contain a break
    • #1005: [java] CloneMethodMustImplementCloneable triggers for interfaces
    • #1669: [java] NullAssignment - FP with ternay and null as constructor argument
    • #1899: [java] Recognize @SuppressWanings(“fallthrough”) for MissingBreakInSwitch
    • #2320: [java] NullAssignment - FP with ternary and null as method argument
    • #2532: [java] AvoidDecimalLiteralsInBigDecimalConstructor can not detect the case new BigDecimal(Expression)
    • #2579: [java] MissingBreakInSwitch detects the lack of break in the last case
    • #2880: [java] CompareObjectsWithEquals - false negative with type res
    • #2893: [java] Remove special cases from rule EmptyCatchBlock
    • #2894: [java] Improve MissingBreakInSwitch
    • #3071: [java] BrokenNullCheck FP with PMD 6.30.0
    • #3087: [java] UnnecessaryBooleanAssertion overlaps with SimplifiableTestAssertion
    • #3100: [java] UseCorrectExceptionLogging FP in 6.31.0
    • #3173: [java] UseProperClassLoader false positive
    • #3351: [java] ConstructorCallsOverridableMethod ignores abstract methods
    • #3400: [java] AvoidUsingOctalValues FN with underscores
    • #3843: [java] UseEqualsToCompareStrings should consider return type
    • #4356: [java] Fix NPE in CloseResourceRule
    • #4449: [java] AvoidAccessibilityAlteration: Possible false positive in AvoidAccessibilityAlteration rule when using Lambda expression
    • #4493: [java] MissingStaticMethodInNonInstantiatableClass: false-positive about @Inject
    • #4505: [java] ImplicitSwitchFallThrough NPE in PMD 7.0.0-rc1
    • #4513: [java] UselessOperationOnImmutable various false negatives with String
    • #4514: [java] AvoidLiteralsInIfCondition false positive and negative for String literals when ignoreExpressions=true
  • java-multithreading
    • #2537: [java] DontCallThreadRun can’t detect the case that call run() in this.run()
    • #2538: [java] DontCallThreadRun can’t detect the case that call run() in foo.bar.run()
    • #2577: [java] UseNotifyAllInsteadOfNotify falsely detect a special case with argument: foo.notify(bar)
    • #4483: [java] NonThreadSafeSingleton false positive with double-checked locking
  • java-performance
    • #1224: [java] InefficientEmptyStringCheck false negative in anonymous class
    • #2587: [java] AvoidArrayLoops could also check for list copy through iterated List.add()
    • #2712: [java] SimplifyStartsWith false-positive with AssertJ
    • #3486: [java] InsufficientStringBufferDeclaration: Fix NPE
    • #3848: [java] StringInstantiation: false negative when using method result
  • kotlin
    • #419: [kotlin] Add support for Kotlin
    • #4389: [kotlin] Update grammar to version 1.8
  • swift
    • #1877: [swift] Feature/swift rules
    • #1882: [swift] UnavailableFunction Swift rule
  • xml
    • #1800: [xml] Unimplement org.w3c.dom.Node from the XmlNodeWrapper

✨ External Contributions

  • #1658: [core] Node support for Antlr-based languages - Matías Fraga (@matifraga)
  • #1698: [core] [swift] Antlr Base Parser adapter and Swift Implementation - Lucas Soncini (@lsoncini)
  • #1774: [core] Antlr visitor rules - Lucas Soncini (@lsoncini)
  • #1877: [swift] Feature/swift rules - Matías Fraga (@matifraga)
  • #1881: [doc] Add ANTLR documentation - Matías Fraga (@matifraga)
  • #1882: [swift] UnavailableFunction Swift rule - Tomás de Lucca (@tomidelucca)
  • #2830: [apex] Apexlink POC - Kevin Jones (@nawforce)
  • #3866: [core] Add CLI Progress Bar - @JerritEic (@JerritEic)
  • #4402: [javascript] CPD: add support for Typescript using antlr4 grammar - Paul Guyot (@pguyot)
  • #4403: [julia] CPD: Add support for Julia code duplication - Wener (@wener-tiobe)
  • #4412: [doc] Added new error msg to ConstantsInInterface - David Ljunggren (@dague1)
  • #4428: [apex] ApexBadCrypto bug fix for #4427 - inline detection of hard coded values - Steven Stearns (@sfdcsteve)
  • #4444: [java] CommentDefaultAccessModifier - ignore org.junit.jupiter.api.extension.RegisterExtension by default - Nirvik Patel (@nirvikpatel)
  • #4450: [java] Fix #4449 AvoidAccessibilityAlteration: Correctly handle Lambda expressions in PrivilegedAction scenarios - Seren (@mohui1999)
  • #4452: [doc] Update PMD_APEX_ROOT_DIRECTORY documentation reference - nwcm (@nwcm)
  • #4474: [java] ImmutableField: False positive with lombok (fixes #4254) - Pim van der Loos (@PimvanderLoos)
  • #4488: [java] Fix #4477: A false-positive about SignatureDeclareThrowsException - AnnaDev (@LynnBroe)
  • #4494: [java] Fix #4487: A false-positive about UnnecessaryConstructor and @Inject and @Autowired - AnnaDev (@LynnBroe)
  • #4495: [java] Fix #4493: false-positive about MissingStaticMethodInNonInstantiatableClass and @Inject - AnnaDev (@LynnBroe)
  • #4520: [doc] Fix typo: missing closing quotation mark after CPD-END - João Dinis Ferreira (@joaodinissf)

📈 Stats

  • 4557 commits
  • 572 closed tickets & PRs
  • Days since last release: 35

25-March-2023 - 7.0.0-rc1

We’re excited to bring you the next major version of PMD!

Since this is a big release, we provide here only a concise version of the release notes. We prepared a separate page with the full Detailed Release Notes for PMD 7.0.0.

ℹ️ Release Candidates

PMD 7.0.0 is finally almost ready. In order to gather feedback, we are going to ship a couple of release candidates. These are officially available on GitHub and Maven Central and can be used as usual (e.g. as a dependency). We encourage you to try out the new features, but keep in mind that we may introduce API breaking changes between the release candidates. It should be stable enough if you don't use custom rules.

We have still some tasks planned for the next release candidates. You can see the progress in PMD 7 Tracking Issue #3898.

If you find any problem or difficulty while updating from PMD 6, please provide feedback via our issue tracker. That way we can improve the experience for all.

Table Of Contents

🚀 Major Features and Enhancements

New official logo

The new official logo of PMD:

New PMD Logo

Revamped Java module

  • Java grammar substantially refactored - more correct regarding the Java Language Specification (JLS)
  • Built-in rules have been upgraded for the changed AST
  • Rewritten type resolution framework and symbol table correctly implements the JLS
  • AST exposes more semantic information (method calls, field accesses)

For more information, see the Detailed Release Notes for PMD 7.

Contributors: Clément Fournier (@oowekyala), Andreas Dangel (@adangel), Juan Martín Sotuyo Dodero (@jsotuyod)

Revamped Command Line Interface

  • unified and consistent Command Line Interface for both Linux/Unix and Windows across our different utilities
  • single script pmd (pmd.bat for Windows) to launch the different utilities:
    • pmd check to run PMD rules and analyze a project
    • pmd cpd to run CPD (copy paste detector)
    • pmd designer to run the PMD Rule Designer
  • progress bar support for pmd check
  • shell completion

Demo

For more information, see the Detailed Release Notes for PMD 7.

Contributors: Juan Martín Sotuyo Dodero (@jsotuyod)

Full Antlr support

  • Antlr based grammars can now be used to build full-fledged PMD rules.
  • Previously, Antlr grammar could only be used for CPD
  • New supported languages: Swift and Kotlin

For more information, see the Detailed Release Notes for PMD 7.

Contributors: Lucas Soncini (@lsoncini), Matías Fraga (@matifraga), Tomás De Lucca (@tomidelucca)

Note that this is just a concise listing of the highlight. For more information on the languages, see the Detailed Release Notes for PMD 7.

New: Swift support

  • use PMD to analyze Swift code with PMD rules
  • initially 4 built-in rules

Contributors: Lucas Soncini (@lsoncini), Matías Fraga (@matifraga), Tomás De Lucca (@tomidelucca)

New: Kotlin support (experimental)

  • use PMD to analyze Kotlin code with PMD rules
  • Support for Kotlin 1.8 grammar
  • initially 2 built-in rules

Changed: JavaScript support

  • latest version supports ES6 and also some new constructs (see Rhino])
  • comments are retained

Changed: Language versions

  • more predefined language versions for each supported language
  • can be used to limit rule execution for specific versions only with minimumLanguageVersion and maximumLanguageVersion attributes.

🌟 New and changed rules

New Rules

Apex

Java

  • UnnecessaryBoxing reports boxing and unboxing conversions that may be made implicit.

Kotlin

Swift

Changed Rules

Java

  • UnnecessaryFullyQualifiedName: the rule has two new properties, to selectively disable reporting on static field and method qualifiers. The rule also has been improved to be more precise.
  • UselessParentheses: the rule has two new properties which control how strict the rule should be applied. With ignoreClarifying (default: true) parentheses that are strictly speaking not necessary are allowed, if they separate expressions of different precedence. The other property ignoreBalancing (default: true) is similar, in that it allows parentheses that help reading and understanding the expressions.
  • LooseCoupling: the rule has a new property to allow some types to be coupled to (allowedTypes).
  • EmptyCatchBlock: CloneNotSupportedException and InterruptedException are not special-cased anymore. Rename the exception parameter to ignored to ignore them.
  • DontImportSun: sun.misc.Signal is not special-cased anymore.
  • UseDiamondOperator: the property java7Compatibility is removed. The rule now handles Java 7 properly without a property.
  • SingularField: Properties checkInnerClasses and disallowNotAssignment are removed. The rule is now more precise and will check these cases properly.
  • UseUtilityClass: The property ignoredAnnotations has been removed.
  • LawOfDemeter: the rule has a new property trustRadius. This defines the maximum degree of trusted data. The default of 1 is the most restrictive.
  • CommentContent: The properties caseSensitive and disallowedTerms are removed. The new property fobiddenRegex can be used now to define the disallowed terms with a single regular expression.

Removed Rules

Many rules, that were previously deprecated have been finally removed. See Detailed Release Notes for PMD 7 for the complete list.

🚨 API

The API of PMD has been growing over the years and needed some cleanup. The goal is, to have a clear separation between a well-defined API and the implementation, which is internal. This should help us in future development.

Also, there are some improvement and changes in different areas. For the detailed description of the changes listed here, see Detailed Release Notes for PMD 7.

  • Miscellaneous smaller changes and cleanups
  • XPath 3.1 support for XPath-based rules
  • Node stream API for AST traversal
  • Metrics framework
  • Testing framework
  • Language Lifecycle and Language Properties

💥 Compatibility and migration notes

See Detailed Release Notes for PMD 7.

🐛 Fixed Issues

  • miscellaneous
    • #881: [all] Breaking API changes for 7.0.0
    • #896: [all] Use slf4j
    • #1431: [ui] Remove old GUI applications (designerold, bgastviewer)
    • #1451: [core] RulesetFactoryCompatibility stores the whole ruleset file in memory as a string
    • #2496: Update PMD 7 Logo on landing page
    • #2497: PMD 7 Logo page
    • #2498: Update PMD 7 Logo in documentation
    • #3797: [all] Use JUnit5
  • ant
    • #4080: [ant] Split off Ant integration into a new submodule
  • core
    • #880: [core] Make visitors generic
    • #1622: [core] NodeStream API
    • #1687: [core] Deprecate and Remove XPath 1.0 support
    • #1785: [core] Allow abstract node types to be valid rulechain visits
    • #1825: [core] Support NoAttribute for XPath
    • #2038: [core] Remove DCD
    • #2218: [core] isFindBoundary should not be an attribute
    • #2234: [core] Consolidate PMD CLI into a single command
    • #2239: [core] Merging Javacc build scripts
    • #2518: [core] Language properties
    • #2602: [core] Remove ParserOptions
    • #2614: [core] Upgrade Saxon, add XPath 3.1, remove Jaxen
    • #2696: [core] Remove DFA
    • #2821: [core] Rule processing error filenames are missing paths
    • #2873: [core] Utility classes in pmd 7
    • #2885: [core] Error recovery mode
    • #3203: [core] Replace RuleViolationFactory implementations with ViolationDecorator
    • #3692: [core] Analysis listeners
    • #3782: [core] Language lifecycle
    • #3815: [core] Update Saxon HE to 10.7
    • #3893: [core] Text documents
    • #3902: [core] Violation decorators
    • #3918: [core] Make LanguageRegistry non static
    • #3922: [core] Better error reporting for the ruleset parser
    • #4035: [core] ConcurrentModificationException in DefaultRuleViolationFactory
    • #4120: [core] Explicitly name all language versions
    • #4353: [core] Micro optimizations for Node API
    • #4365: [core] Improve benchmarking
    • #4420: [core] Remove PMD.EOL
  • cli
    • #2234: [core] Consolidate PMD CLI into a single command
    • #3828: [core] Progress reporting
    • #4079: [cli] Split off CLI implementation into a pmd-cli submodule
  • testing
    • #2435: [test] Remove duplicated Dummy language module
    • #4234: [test] Tests that change the logging level do not work

Language specific fixes:

  • apex
    • #1937: [apex] Apex should only have a single RootNode
    • #1648: [apex,vf] Remove CodeClimate dependency
    • #1750: [apex] Remove apex statistical rules
    • #2836: [apex] Remove Apex ProjectMirror
    • #4427: [apex] ApexBadCrypto test failing to detect inline code
  • apex-design
    • #2667: [apex] Integrate nawforce/ApexLink to build robust Unused rule
  • java
    • #520: [java] Allow @SuppressWarnings with constants instead of literals
    • #864: [java] Similar/duplicated implementations for determining FQCN
    • #905: [java] Add new node for anonymous class declaration
    • #910: [java] AST inconsistency between primitive and reference type arrays
    • #997: [java] Java8 parsing corner case with annotated array types
    • #998: [java] AST inconsistencies around FormalParameter
    • #1019: [java] Breaking Java Grammar changes for PMD 7.0.0
    • #1124: [java] ImmutableList implementation in the qname codebase
    • #1128: [java] Improve ASTLocalVariableDeclaration
    • #1150: [java] ClassOrInterfaceType AST improvements
    • #1207: [java] Resolve explicit types using FQCNs, without hitting the classloader
    • #1367: [java] Parsing error on annotated inner class
    • #1661: [java] About operator nodes
    • #2366: [java] Remove qualified names
    • #2819: [java] GLB bugs in pmd 7
    • #3763: [java] Ambiguous reference error in valid code
    • #3749: [java] Improve isOverridden in ASTMethodDeclaration
    • #3750: [java] Make symbol table support instanceof pattern bindings
    • #3752: [java] Expose annotations in symbol API
    • #4237: [java] Cleanup handling of Java comments
    • #4317: [java] Some AST nodes should not be TypeNodes
    • #4359: [java] Type resolution fails with NPE when the scope is not a type declaration
    • #4367: [java] Move testrule TypeResTest into internal
  • java-bestpractices
    • #342: [java] AccessorMethodGeneration: Name clash with another public field not properly handled
    • #755: [java] AccessorClassGeneration false positive for private constructors
    • #770: [java] UnusedPrivateMethod yields false positive for counter-variant arguments
    • #807: [java] AccessorMethodGeneration false positive with overloads
    • #833: [java] ForLoopCanBeForeach should consider iterating on this
    • #1189: [java] UnusedPrivateMethod false positive from inner class via external class
    • #1205: [java] Improve ConstantsInInterface message to mention alternatives
    • #1212: [java] Don’t raise JUnitTestContainsTooManyAsserts on JUnit 5’s assertAll
    • #1422: [java] JUnitTestsShouldIncludeAssert false positive with inherited @Rule field
    • #1565: [java] JUnitAssertionsShouldIncludeMessage false positive with AssertJ
    • #1747: [java] PreserveStackTrace false-positive
    • #1969: [java] MissingOverride false-positive triggered by package-private method overwritten in another package by extending class
    • #1998: [java] AccessorClassGeneration false-negative: subclass calls private constructor
    • #2130: [java] UnusedLocalVariable: false-negative with array
    • #2147: [java] JUnitTestsShouldIncludeAssert - false positives with lambdas and static methods
    • #2464: [java] LooseCoupling must ignore class literals: ArrayList.class
    • #2542: [java] UseCollectionIsEmpty can not detect the case foo.bar().size()
    • #2650: [java] UseTryWithResources false positive when AutoCloseable helper used
    • #2796: [java] UnusedAssignment false positive with call chains
    • #2797: [java] MissingOverride long-standing issues
    • #2806: [java] SwitchStmtsShouldHaveDefault false-positive with Java 14 switch non-fallthrough branches
    • #2822: [java] LooseCoupling rule: Extend to cover user defined implementations and interfaces
    • #2843: [java] Fix UnusedAssignment FP with field accesses
    • #2882: [java] UseTryWithResources - false negative for explicit close
    • #2883: [java] JUnitAssertionsShouldIncludeMessage false positive with method call
    • #2890: [java] UnusedPrivateMethod false positive with generics
    • #2946: [java] SwitchStmtsShouldHaveDefault false positive on enum inside enums
    • #3672: [java] LooseCoupling - fix false positive with generics
    • #3675: [java] MissingOverride - fix false positive with mixing type vars
  • java-codestyle
    • #1208: [java] PrematureDeclaration rule false-positive on variable declared to measure time
    • #1429: [java] PrematureDeclaration as result of method call (false positive)
    • #1673: [java] UselessParentheses false positive with conditional operator
    • #1790: [java] UnnecessaryFullyQualifiedName false positive with enum constant
    • #1918: [java] UselessParentheses false positive with boolean operators
    • #2134: [java] PreserveStackTrace not handling Throwable.addSuppressed(...)
    • #2299: [java] UnnecessaryFullyQualifiedName false positive with similar package name
    • #2391: [java] UseDiamondOperator FP when expected type and constructed type have a different parameterization
    • #2528: [java] MethodNamingConventions - JUnit 5 method naming not support ParameterizedTest
    • #2739: [java] UselessParentheses false positive for string concatenation
    • #2748: [java] UnnecessaryCast false positive with unchecked cast
    • #2973: [java] New rule: UnnecessaryBoxing
    • #3195: [java] Improve rule UnnecessaryReturn to detect more cases
    • #3218: [java] Generalize UnnecessaryCast to flag all unnecessary casts
    • #3221: [java] PrematureDeclaration false positive for unused variables
    • #3238: [java] Improve ExprContext, fix FNs of UnnecessaryCast
    • #3500: [java] UnnecessaryBoxing - check for Integer.valueOf(String) calls
    • #4357: [java] Fix IllegalStateException in UseDiamondOperator rule
  • java-design
    • #1014: [java] LawOfDemeter: False positive with lambda expression
    • #1605: [java] LawOfDemeter: False positive for standard UTF-8 charset name
    • #2175: [java] LawOfDemeter: False positive for chained methods with generic method call
    • #2179: [java] LawOfDemeter: False positive with static property access - should treat class-level property as global object, not dot-accessed property
    • #2180: [java] LawOfDemeter: False positive with Thread and ThreadLocalRandom
    • #2182: [java] LawOfDemeter: False positive with package-private access
    • #2188: [java] LawOfDemeter: False positive with fields assigned to local vars
    • #2536: [java] ClassWithOnlyPrivateConstructorsShouldBeFinal can’t detect inner class
    • #3668: [java] ClassWithOnlyPrivateConstructorsShouldBeFinal - fix FP with inner private classes
    • #3754: [java] SingularField false positive with read in while condition
    • #3786: [java] SimplifyBooleanReturns should consider operator precedence
    • #4238: [java] Make LawOfDemeter not use the rulechain
  • java-documentation
    • #4369: [java] Improve CommentSize
    • #4416: [java] Fix reported line number in CommentContentRule
  • java-errorprone
    • #659: [java] MissingBreakInSwitch - last default case does not contain a break
    • #1005: [java] CloneMethodMustImplementCloneable triggers for interfaces
    • #1669: [java] NullAssignment - FP with ternay and null as constructor argument
    • #1899: [java] Recognize @SuppressWanings(“fallthrough”) for MissingBreakInSwitch
    • #2320: [java] NullAssignment - FP with ternary and null as method argument
    • #2532: [java] AvoidDecimalLiteralsInBigDecimalConstructor can not detect the case new BigDecimal(Expression)
    • #2579: [java] MissingBreakInSwitch detects the lack of break in the last case
    • #2880: [java] CompareObjectsWithEquals - false negative with type res
    • #2893: [java] Remove special cases from rule EmptyCatchBlock
    • #2894: [java] Improve MissingBreakInSwitch
    • #3071: [java] BrokenNullCheck FP with PMD 6.30.0
    • #3087: [java] UnnecessaryBooleanAssertion overlaps with SimplifiableTestAssertion
    • #3100: [java] UseCorrectExceptionLogging FP in 6.31.0
    • #3173: [java] UseProperClassLoader false positive
    • #3351: [java] ConstructorCallsOverridableMethod ignores abstract methods
    • #3400: [java] AvoidUsingOctalValues FN with underscores
    • #4356: [java] Fix NPE in CloseResourceRule
  • java-multithreading
    • #2537: [java] DontCallThreadRun can’t detect the case that call run() in this.run()
    • #2538: [java] DontCallThreadRun can’t detect the case that call run() in foo.bar.run()
    • #2577: [java] UseNotifyAllInsteadOfNotify falsely detect a special case with argument: foo.notify(bar)
  • java-performance
    • #1224: [java] InefficientEmptyStringCheck false negative in anonymous class
    • #2587: [java] AvoidArrayLoops could also check for list copy through iterated List.add()
    • #2712: [java] SimplifyStartsWith false-positive with AssertJ
    • #3486: [java] InsufficientStringBufferDeclaration: Fix NPE
  • kotlin
    • #419: [kotlin] Add support for Kotlin
    • #4389: [kotlin] Update grammar to version 1.8
  • swift
    • #1877: [swift] Feature/swift rules
    • #1882: [swift] UnavailableFunction Swift rule
  • xml
    • #1800: [xml] Unimplement org.w3c.dom.Node from the XmlNodeWrapper

✨ External Contributions

📈 Stats

  • 4416 commits
  • 464 closed tickets & PRs
  • Days since last release: 28

25-February-2023 - 6.55.0

The PMD team is pleased to announce PMD 6.55.0.

This is a minor release.

Table Of Contents

New and noteworthy

PMD 7 Development

This release is the last planned release of PMD 6. The first version 6.0.0 was released in December 2017. Over the course of more than 5 years we published almost every month a new minor version of PMD 6 with new features and improvements.

Already in November 2018 we started in parallel the development of the next major version 7.0.0, and we are now in the process of finalizing the scope of the major version. We want to release a couple of release candidates before publishing the final version 7.0.0.

We plan to release 7.0.0-rc1 soon. You can see the progress in PMD 7 Tracking Issue #3898.

Java 20 Support

This release of PMD brings support for Java 20. There are no new standard language features.

PMD supports JEP 433: Pattern Matching for switch (Fourth Preview) and JEP 432: Record Patterns (Second Preview) as preview language features.

In order to analyze a project with PMD that uses these language features, you’ll need to enable it via the environment variable PMD_JAVA_OPTS and select the new language version 20-preview:

export PMD_JAVA_OPTS=--enable-preview
./run.sh pmd --use-version java-20-preview ...

T-SQL support

Thanks to the contribution from Paul Guyot PMD now has CPD support for T-SQL (Transact-SQL).

Being based on a proper Antlr grammar, CPD can:

Fixed Issues

  • core
    • #4395: [core] Support environment variable CLASSPATH with pmd.bat under Windows
  • java
    • #4333: [java] Support JDK 20
  • java-errorprone
    • #4393: [java] MissingStaticMethodInNonInstantiatableClass false-positive for Lombok’s @UtilityClass for classes with non-private fields

API Changes

Go

  • The LanguageModule of Go, that only supports CPD execution, has been deprecated. This language is not fully supported by PMD, so having a language module does not make sense. The functionality of CPD is not affected by this change. The following class has been deprecated and will be removed with PMD 7.0.0:

Java

  • Support for Java 18 preview language features have been removed. The version “18-preview” is no longer available.
  • The experimental class net.sourceforge.pmd.lang.java.ast.ASTGuardedPattern has been removed.

External Contributions

  • #4384: [swift] Add more swift 5.x support (#unavailable mainly) - Richard B. (@kenji21)
  • #4390: Add support for T-SQL using Antlr4 lexer - Paul Guyot (@pguyot)
  • #4392: [java] Fix #4393 MissingStaticMethodInNonInstantiatableClass: Fix false-positive for field-only class - Dawid Ciok (@dawiddc)

Stats

  • 40 commits
  • 11 closed tickets & PRs
  • Days since last release: 28

28-January-2023 - 6.54.0

The PMD team is pleased to announce PMD 6.54.0.

This is a minor release.

Table Of Contents

New and noteworthy

New report format html-report-v2.xslt

Thanks to @mohan-chinnappan-n a new PMD report format has been added which features a data table with charting functions. It uses an XSLT stylesheet to convert PMD’s XML format into HTML.

See the example report.

Fixed Issues

  • apex-bestpractices
    • #2669: [apex] UnusedLocalVariable false positive in dynamic SOQL
  • core
    • #4026: [cli] Filenames printed as absolute paths in the report despite parameter --short-names
    • #4279: [core] Can not set ruleset property value to empty
    • #4329: [core] Refactor usage of snakeyaml
    • #4340: [core] Allow to filter found matches in CPDReport
  • java
    • #4364: [java] Parsing error with textblock containing quote followed by two backslashes
  • testing
    • #4236: [test] kotest logs look broken

API Changes

PMD CLI

  • PMD now supports a new --relativize-paths-with flag (or short -z), which replaces --short-names. It serves the same purpose: Shortening the pathnames in the reports. However, with the new flag it’s possible to explicitly define one or more pathnames that should be used as the base when creating relative paths. The old flag --short-names is deprecated.

Deprecated APIs

For removal
Internal APIs
Experimental APIs
  • CPDReport has a new method which limited mutation of a given report:
    • filterMatches creates a new CPD report with some matches removed with a given predicate based filter.

External Contributions

  • #4110: [apex] Feature/unused variable bind false positive with dynamic SOQL - Thomas Prouvot (@tprouvot)
  • #4125: [core] New report format html-report-v2.xslt to provide html with datatable and chart features - Mohan Chinnappan - (@mohan-chinnappan-n)
  • #4280: [apex] Deprecate ApexRootNode.getApexVersion - Aaron Hurst (@aaronhurst-google)
  • #4285: [java] CommentDefaultAccessModifier - add co.elastic.clients.util.VisibleForTesting as default suppressed annotation - Matthew Luckam (@mluckam)

Stats

  • 107 commits
  • 19 closed tickets & PRs
  • Days since last release: 27

31-December-2022 - 6.53.0

The PMD team is pleased to announce PMD 6.53.0.

This is a minor release.

Table Of Contents

New and noteworthy

Modified rules

  • The Java rule UnusedPrivateField has a new property reportForAnnotations. This is a list of fully qualified names of the annotation types that should be reported anyway. If an unused field has any of these annotations, then it is reported. If it has any other annotation, then it is still considered to be used and is not reported.

Deprecated rules

Fixed Issues

  • core
    • #4248: [core] Can’t analyze sources in zip files
  • apex-security
    • #4146: [apex] ApexCRUDViolation: Recognize User Mode in SOQL + DML
  • java
    • #4266: [java] PMD fails to process a record with lambda in compact constructor
  • java-bestpractices
    • #4166: [java] UnusedPrivateField doesn’t find annotated unused private fields anymore
    • #4250: [java] WhileLoopWithLiteralBoolean - false negative with complex expressions still occurs in PMD 6.52.0
  • java-design
    • #2127: [java] Deprecate rules ExcessiveClassLength and ExcessiveMethodLength
  • java-errorprone
    • #4164: [java][doc] AvoidAssertAsIdentifier and AvoidEnumAsIdentifier - clarify use case
  • java-multithreading
    • #4210: [java] DoNotUseThreads report duplicate warnings

API Changes

Deprecated APIs

For removal

These classes / APIs have been deprecated and will be removed with PMD 7.0.0.

External Contributions

  • #4244: [apex] ApexCRUDViolation: user mode and system mode with test cases added - Tarush Singh (@Tarush-Singh35)
  • #4274: [java] Fix finding lambda scope in record compact constructor - kdebski85 (@kdebski85)

Stats

  • 43 commits
  • 17 closed tickets & PRs
  • Days since last release: 35

26-November-2022 - 6.52.0

The PMD team is pleased to announce PMD 6.52.0.

This is a minor release.

Table Of Contents

New and noteworthy

New rules

<rule ref="category/java/design.xml/InvalidJavaBean"/>

Renamed rules

  • The Java rule BeanMembersShouldSerialize has been renamed to NonSerializableClass. It has been revamped to only check for classes that are marked with Serializable and reports each field in it, that is not serializable.

    The property prefix has been deprecated, since in a serializable class all fields have to be serializable regardless of the name.

Modified rules

  • The rule ClassNamingConventions has a new property testClassPattern, which is applied to test classes. By default, test classes should end with the suffix “Test”. Test classes are top-level classes, that either inherit from JUnit 3 TestCase or have at least one method annotated with the Test annotations from JUnit4/5 or TestNG.

  • The property ignoredAnnotations of rule ImmutableField has been deprecated and doesn’t have any effect anymore. Since PMD 6.47.0, the rule only considers fields, that are initialized once and never changed. If the field is just declared but never explicitly initialized, it won’t be reported. That’s the typical case when a framework sets the field value by reflection. Therefore, the property is not needed anymore. If there is a special case where this rule misidentifies fields as immutable, then the rule should be suppressed for these fields explicitly.

Fixed Issues

  • cli
    • #4215: NullPointerException when trying to open designer
  • doc
    • #4207: [doc] List all languages in rule doc
  • java
    • #3643: [java] More parser edge cases
    • #4152: [java] Parse error on array type annotations
  • java-codestyle
    • #2867: [java] Separate pattern for test classes in ClassNamingConventions rule for Java
    • #4201: [java] CommentDefaultAccessModifier should consider lombok’s @Value
  • java-design
    • #4175: [java] ImmutableField - deprecate property ignoredAnnotations
    • #4177: [java] New Rule InvalidJavaBean
    • #4188: [java] ClassWithOnlyPrivateConstructorsShouldBeFinal false positive with Lombok’s @NoArgsConstructor
    • #4189: [java] AbstractClassWithoutAnyMethod should consider lombok’s @AllArgsConstructor
    • #4200: [java] ClassWithOnlyPrivateConstructorsShouldBeFinal should consider lombok’s @Value
  • java-errorprone
    • #1668: [java] BeanMembersShouldSerialize is extremely noisy
    • #4172: [java] InvalidLogMessageFormat false positive on externally formatted strings
    • #4174: [java] MissingStaticMethodInNonInstantiatableClass does not consider nested builder class
    • #4176: [java] Rename BeanMembersShouldSerialize to NonSerializableClass
    • #4185: [java] InvalidLogMessageFormat rule produces a NPE
    • #4224: [java] MissingStaticMethodInNonInstantiatableClass should consider Lombok’s @UtilityClass
    • #4225: [java] MissingStaticMethodInNonInstantiatableClass should consider Lombok’s @NoArgsConstructor
  • java-performance
    • #4183: [java] AvoidArrayLoops regression: from false negative to false positive with final variables

API Changes

PMD CLI

  • PMD now supports a new --use-version flag, which receives a language-version pair (such as java-8 or apex-54). This supersedes the usage of -language / -l and -version / -v, allowing for multiple versions to be set in a single run. PMD 7 will completely remove support for -language and -version in favor of this new flag.

  • Support for -V is being deprecated in favor of --verbose in preparation for PMD 7. In PMD 7, -v will enable verbose mode and -V will show the PMD version for consistency with most Unix/Linux tools.

  • Support for -min is being deprecated in favor of --minimum-priority for consistency with most Unix/Linux tools, where -min would be equivalent to -m -i -n.

CPD CLI

  • CPD now supports using -d or --dir as an alias to --files, in favor of consistency with PMD. PMD 7 will remove support for --files in favor of these new flags.

Linux run.sh parameters

  • Using run.sh cpdgui will now warn about it being deprecated. Use run.sh cpd-gui instead.

  • The old designer (run.sh designerold) is completely deprecated and will be removed in PMD 7. Switch to the new JavaFX designer: run.sh designer.

  • The old visual AST viewer (run.sh bgastviewer) is completely deprecated and will be removed in PMD 7. Switch to the new JavaFX designer: run.sh designer for a visual tool, or use run.sh ast-dump for a text-based alternative.

Deprecated API

External Contributions

  • #4184: [java][doc] TestClassWithoutTestCases - fix small typo in description - Valery Yatsynovich (@valfirst)
  • #4198: [doc] Add supported CPD languages - Jeroen van Wilgenburg (@jvwilge)
  • #4202: [java] Fix #4200 and #4201: ClassWithOnlyPrivateConstructorsShouldBeFinal, CommentDefaultAccessModifier: Exclude lombok @Value annotation - Lynn (@LynnBroe)
  • #4205: [doc] Clarify Scala support (no built-in rules) - Eldrick Wega (@Eldrick19)
  • #4226: [visualforce] Replace uses of Jorje types in pmd-visualforce - Aaron Hurst (@aaronhurst-google)
  • #4227: [java] Fix #4225 MissingStaticMethodInNonInstantiatableClass: Exclude lombok’s @NoArgsConstructor annotation - Lynn (@LynnBroe)
  • #4228: [java] Fix #4224 MissingStaticMethodInNonInstantiatableClass: Exclude lombok’s UtilityClass - Lynn (@LynnBroe)
  • #4232: [doc] Fixing typos - Andreas Deininger (@deining)

Stats

  • 96 commits
  • 40 closed tickets & PRs
  • Days since last release: 28

29-October-2022 - 6.51.0

The PMD team is pleased to announce PMD 6.51.0.

This is a minor release.

Table Of Contents

New and noteworthy

New Rules

<rule ref="category/apex/bestpractices.xml/ApexUnitTestClassShouldHaveRunAs"/>

The rule is part of the quickstart.xml ruleset.

Modified Rules

  • The Java rule TestClassWithoutTestCases has a new property testClassPattern. This is used to detect empty test classes by name. Previously this rule could only detect empty JUnit3 test cases properly. To switch back to the old behavior, this property can be set to an empty value which disables the test class detection by pattern.

Fixed Issues

  • apex
    • #4149: [apex] New rule: ApexUnitTestClassShouldHaveRunAs
  • doc
    • #4144: [doc] Update docs to reflect supported languages
    • #4163: [doc] Broken links on page “Architecture Decisions”
  • java-bestpractices
    • #4140: [java] [doc] AccessorClassGeneration violations hidden with Java 11
  • java-codestyle
    • #4139: [java] UnnecessaryFullyQualifiedName FP when the same simple class name exists in the current package
  • java-documentation
    • #4141: [java] UncommentedEmptyConstructor FP when constructor annotated with @Autowired
  • java-performance
    • #1167: [java] AvoidArrayLoops false positive on double assignment
    • #2080: [java] StringToString rule false-positive with field access
    • #2692: [java] [doc] AvoidArrayLoops flags copy assignment in same array as sub-optimal
    • #3437: [java] StringToString doesn’t trigger on Bar.class.getSimpleName().toString()
    • #3681: [java] StringToString doesn’t trigger on string literals
    • #3847: [java] AvoidArrayLoops should consider final variables
    • #3977: [java] StringToString false-positive with local method name confusion
    • #4091: [java] AvoidArrayLoops false negative with do-while loops
    • #4148: [java] UseArrayListInsteadOfVector ignores Vector when other classes are imported
  • java-errorprone
    • #929: [java] Inconsistent results with TestClassWithoutTestCases
    • #2636: [java] TestClassWithoutTestCases false positive with JUnit5 ParameterizedTest
  • javascript
    • #4165: [javascript] InaccurateNumericLiteral underscore separator notation false positive

API Changes

No changes.

External Contributions

  • #4142: [java] fix #4141 Update UncommentedEmptyConstructor - ignore @Autowired annotations - Lynn (@LynnBroe)
  • #4147: [java] Added support for Do-While for AvoidArrayLoops - Yasar Shaikh (@yasarshaikh)
  • #4150: [apex] New rule ApexUnitTestClassShouldHaveRunAs #4149 - Thomas Prouvot (@tprouvot)

Stats

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

30-September-2022 - 6.50.0

The PMD team is pleased to announce PMD 6.50.0.

This is a minor release.

Table Of Contents

New and noteworthy

Lua now supports additionally Luau

This release of PMD adds support for Luau, a gradually typed language derived from Lua. This means, that the Lua language in PMD can now parse both Lua and Luau.

Modified rules

  • The Java rule UnusedPrivateField now ignores private fields, if the fields are annotated with any annotation or the enclosing class has any annotation. Annotations often enable a framework (such as dependency injection, mocking or e.g. Lombok) which use the fields by reflection or other means. This usage can’t be detected by static code analysis. Previously these frameworks where explicitly allowed by listing their annotations in the property “ignoredAnnotations”, but that turned out to be prone of false positive for any not explicitly considered framework. That’s why the property “ignoredAnnotations” has been deprecated for this rule.
  • The Java rule CommentDefaultAccessModifier now by default ignores JUnit5 annotated methods. This behavior can be customized using the property ignoredAnnotations.

Fixed Issues

  • cli
    • #4118: [cli] run.sh designer reports “integer expression expected”
  • core
    • #4116: [core] Missing –file arg in TreeExport CLI example
  • doc
    • #4072: [doc] Add architecture decision records
    • #4109: [doc] Add page for 3rd party rulesets
    • #4124: [doc] Fix typos in Java rule docs
  • java
    • #3431: [java] Add sample java project to regression-tester which uses new language constructs
  • java-bestpractices
    • #4033: [java] UnusedPrivateField - false positive with Lombok @ToString.Include
    • #4037: [java] UnusedPrivateField - false positive with Spring @SpyBean
  • java-codestyle
    • #3859: [java] CommentDefaultAccessModifier is triggered in JUnit5 test class
    • #4085: [java] UnnecessaryFullyQualifiedName false positive when nested and non-nested classes with the same name and in the same package are used together
    • #4133: [java] UnnecessaryFullyQualifiedName - FP for inner class pkg.ClassA.Foo implementing pkg.Foo
  • java-design
    • #4090: [java] FinalFieldCouldBeStatic false positive with non-static synchronized block (regression in 6.48, worked with 6.47)
  • java-errorprone
    • #1718: [java] ConstructorCallsOverridableMethod false positive when calling super method
    • #2348: [java] ConstructorCallsOverridableMethod occurs when unused overloaded method is defined
    • #4099: [java] ConstructorCallsOverridableMethod should consider method calls with var access
  • scala
    • #4138: [scala] Upgrade scala-library to 2.12.7 / 2.13.9 and scalameta to 4.6.0

API Changes

CPD CLI

  • CPD now supports the --ignore-literal-sequences argument when analyzing Lua code.

Financial Contributions

Many thanks to our sponsors:

External Contributions

  • #4066: [lua] Add support for Luau syntax and skipping literal sequences in CPD - Matt Hargett (@matthargett)
  • #4100: [java] Update UnusedPrivateFieldRule - ignore any annotations - Lynn (@LynnBroe)
  • #4116: [core] Fix missing –file arg in TreeExport CLI example - mohan-chinnappan-n (@mohan-chinnappan-n)
  • #4124: [doc] Fix typos in Java rule docs - Piotrek Żygieło (@pzygielo)
  • #4128: [java] Fix False-positive UnnecessaryFullyQualifiedName when nested and non-nest… #4103 - Oleg Andreych (@OlegAndreych)
  • #4130: [ci] GitHub Workflows security hardening - Alex (@sashashura)
  • #4131: [doc] TooFewBranchesForASwitchStatement - Use “if-else” instead of “if-then” - Suvashri (@Suvashri)
  • #4137: [java] Fixes 3859: Exclude junit5 test methods from the commentDefaultAccessModifierRule - Luis Alcantar (@lfalcantar)

Stats

  • 100 commits
  • 26 closed tickets & PRs
  • Days since last release: 29

31-August-2022 - 6.49.0

The PMD team is pleased to announce PMD 6.49.0.

This is a minor release.

Table Of Contents

New and noteworthy

Updated PMD Designer

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

Fixed Issues

  • apex
    • #4096: [apex] ApexAssertionsShouldIncludeMessage and ApexUnitTestClassShouldHaveAsserts: support new Assert class (introduced with Apex v56.0)
  • core
    • #3970: [core] FileCollector.addFile ignores language parameter
  • java-codestyle
    • #4082: [java] UnnecessaryImport false positive for on-demand imports of nested classes

API Changes

Deprecated API

External Contributions

  • #4081: [apex] Remove Jorje leaks outside ast package - @eklimo
  • #4083: [java] UnnecessaryImport false positive for on-demand imports of nested classes (fix for #4082) - @abyss638
  • #4092: [apex] Implement ApexQualifiableNode for ASTUserEnum - @aaronhurst-google
  • #4095: [core] CPD: Added begin and end token to XML reports - @pacvz
  • #4097: [apex] ApexUnitTestClassShouldHaveAssertsRule: Support new Assert class (Apex v56.0) - @tprouvot
  • #4104: [doc] Add MegaLinter in the list of integrations - @nvuillam

Stats

  • 49 commits
  • 10 closed tickets & PRs
  • Days since last release: 32

30-July-2022 - 6.48.0

The PMD team is pleased to announce PMD 6.48.0.

This is a minor release.

Table Of Contents

New and noteworthy

Java 19 Support

This release of PMD brings support for Java 19. There are no new standard language features.

PMD supports JEP 427: Pattern Matching for switch (Third Preview) and JEP 405: Record Patterns (Preview) as preview language features.

In order to analyze a project with PMD that uses these language features, you’ll need to enable it via the environment variable PMD_JAVA_OPTS and select the new language version 19-preview:

export PMD_JAVA_OPTS=--enable-preview
./run.sh pmd -language java -version 19-preview ...

Note: Support for Java 17 preview language features have been removed. The version “17-preview” is no longer available.

Gherkin support

Thanks to the contribution from Anne Brouwers PMD now has CPD support for the Gherkin language. It is used to defined test cases for the Cucumber testing tool for behavior-driven development.

Being based on a proper Antlr grammar, CPD can:

Fixed Issues

  • apex
    • #4056: [apex] ApexSOQLInjection: Add support count query
  • core
    • #3796: [core] CPD should also provide a --debug flag
    • #4021: [core] CPD: Add total number of tokens to XML reports
    • #4031: [core] If report is written to stdout, stdout should not be closed
    • #4051: [doc] Additional rulesets are not listed in documentation
    • #4053: [core] Allow building PMD under Java 18+
  • java
    • #4015: [java] Support JDK 19
  • java-bestpractices
    • #3455: [java] WhileLoopWithLiteralBoolean - false negative with complex expressions
  • java-design
    • #3729: [java] TooManyMethods ignores “real” methods which are named like getters or setters
    • #3949: [java] FinalFieldCouldBeStatic - false negative with unnecessary parenthesis
  • java-performance
    • #3625: [java] AddEmptyString - false negative with empty var
  • lua
    • #4061: [lua] Fix several related Lua parsing issues found when using CPD
  • test
    • #3302: [test] Improve xml test schema
    • #3758: [test] Move pmd-test to java 8
    • #3976: [test] Extract xml schema module

API Changes

CPD CLI

  • CPD has a new CLI option --debug. This option has the same behavior as in PMD. It enables more verbose logging output.

Rule Test Framework

  • The module “pmd-test”, which contains support classes to write rule tests, now requires Java 8. If you depend on this module for testing your own custom rules, you’ll need to make sure to use at least Java 8.
  • The new module “pmd-test-schema” contains now the XSD schema and the code to parse the rule test XML files. The schema has been extracted in order to easily share it with other tools like the Rule Designer or IDE plugins.
  • Test schema changes:
    • The attribute isRegressionTest of test-code is deprecated. The new attribute disabled should be used instead for defining whether a rule test should be skipped or not.
    • The attributes reinitializeRule and useAuxClasspath of test-code are deprecated and assumed true. They will not be replaced.
    • The new attribute focused of test-code allows disabling all tests except the focused one temporarily.
  • More information about the rule test framework can be found in the documentation: Testing your rules

Deprecated API

  • The experimental Java AST class ASTGuardedPattern has been deprecated and will be removed. It was introduced for Java 17 and Java 18 Preview as part of pattern matching for switch, but it is no longer supported with Java 19 Preview.
  • The interface CPDRenderer is deprecated. For custom CPD renderers the new interface CPDReportRenderer should be used.
  • The class TestDescriptor is deprecated, replaced with RuleTestDescriptor.
  • Many methods of RuleTst have been deprecated as internal API.

Experimental APIs

Internal API

Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. You can identify them with the @InternalApi annotation. You’ll also get a deprecation warning.

Financial Contributions

Many thanks to our sponsors:

External Contributions

Stats

  • 102 commits
  • 26 closed tickets & PRs
  • Days since last release: 35

25-June-2022 - 6.47.0

The PMD team is pleased to announce PMD 6.47.0.

This is a minor release.

Table Of Contents

Fixed Issues

  • core
    • #3999: [cli] All files are analyzed despite parameter --file-list
    • #4009: [core] Cannot build PMD with Temurin 17
  • java-bestpractices
    • #3824: [java] UnusedPrivateField: Do not flag fields annotated with @Version
    • #3825: [java] UnusedPrivateField: Do not flag fields annotated with @Id or @EmbeddedId
  • java-design
    • #3823: [java] ImmutableField: Do not flag fields in @Entity
    • #3981: [java] ImmutableField reports fields annotated with @Value (Spring)
    • #3998: [java] ImmutableField reports fields annotated with @Captor (Mockito)
    • #4004: [java] ImmutableField reports fields annotated with @GwtMock (GwtMockito) and @Spy (Mockito)
    • #4008: [java] ImmutableField not reporting fields that are only initialized in the declaration
    • #4011: [java] ImmutableField: Do not flag fields annotated with @Inject
    • #4020: [java] ImmutableField reports fields annotated with @FindBy and @FindBys (Selenium)
  • java-errorprone
    • #3936: [java] AvoidFieldNameMatchingMethodName should consider enum class
    • #3937: [java] AvoidDuplicateLiterals - uncompilable test cases

API Changes

No changes.

External Contributions

  • #3985: [java] Fix false negative problem about Enum in AvoidFieldNameMatchingMethodName #3936 - @Scrsloota
  • #3993: [java] AvoidDuplicateLiterals - Add the method “buz” definition to test cases - @dalizi007
  • #4002: [java] ImmutableField - Ignore fields annotated with @Value (Spring) or @Captor (Mockito) - @jjlharrison
  • #4003: [java] UnusedPrivateField - Ignore fields annotated with @Id/@EmbeddedId/@Version (JPA) or @Mock/@Spy/@MockBean (Mockito/Spring) - @jjlharrison
  • #4006: [doc] Fix eclipse plugin update site URL - @shiomiyan
  • #4010: [core] Bump kotlin to version 1.7.0 - @maikelsteneker

Stats

  • 45 commits
  • 23 closed tickets & PRs
  • Days since last release: 27

28-May-2022 - 6.46.0

The PMD team is pleased to announce PMD 6.46.0.

This is a minor release.

Table Of Contents

New and noteworthy

CLI improvements

The PMD CLI now allows repeating the --dir (-d) and --rulesets (-R) options, as well as providing several space-separated arguments to either of them. For instance:

pmd -d src/main/java src/test/java -R rset1.xml -R rset2.xml

This also allows globs to be used on the CLI if your shell supports shell expansion. For instance, the above can be written

pmd -d src/*/java -R rset*.xml

Please use theses new forms instead of using comma-separated lists as argument to these options.

C# Improvements

When executing CPD on C# sources, the option --ignore-annotations is now supported as well. It ignores C# attributes when detecting duplicated code. This option can also be enabled via the CPD GUI. See #3974 for details.

New Rules

This release ships with 2 new Java rules.

  • EmptyControlStatement reports many instances of empty things, e.g. control statements whose body is empty, as well as empty initializers.

    EmptyControlStatement also works for empty for and do loops, while there were previously no corresponding rules.

    This new rule replaces the rules EmptyFinallyBlock, EmptyIfStmt, EmptyInitializer, EmptyStatementBlock, EmptySwitchStatements, EmptySynchronizedBlock, EmptyTryBlock, and EmptyWhileStmt.

<rule ref="category/java/codestyle.xml/EmptyControlStatement"/>

The rule is part of the quickstart.xml ruleset.

  • UnnecessarySemicolon reports semicolons that are unnecessary (so called “empty statements” and “empty declarations”).

    This new rule replaces the rule EmptyStatementNotInLoop.

<rule ref="category/java/codestyle.xml/UnnecessarySemicolon"/>

The rule is part of the quickstart.xml ruleset.

Deprecated Rules

Fixed Issues

  • cli
    • #1445: [core] Allow CLI to take globs as parameters
  • core
    • #2352: [core] Deprecate <lang>-<ruleset> hyphen notation for ruleset references
    • #3787: [core] Internalize some methods in Ant Formatter
    • #3835: [core] Deprecate system properties of CPDCommandLineInterface
    • #3942: [core] common-io path traversal vulnerability (CVE-2021-29425)
  • cs (c#)
    • #3974: [cs] Add option to ignore C# attributes (annotations)
  • go
    • #2752: [go] Error parsing unicode values
  • html
    • #3955: [html] Improvements for handling text and comment nodes
    • #3978: [html] Add additional file extensions htm, xhtml, xht, shtml
  • java
    • #3423: [java] Error processing identifiers with Unicode
  • java-bestpractices
    • #3954: [java] NPE in UseCollectionIsEmptyRule when .size() is called in a record
  • java-design
    • #3874: [java] ImmutableField reports fields annotated with @Autowired (Spring) and @Mock (Mockito)
  • java-errorprone
    • #3096: [java] EmptyStatementNotInLoop FP in 6.30.0 with IfStatement
  • java-performance
    • #3379: [java] UseArraysAsList must ignore primitive arrays
    • #3965: [java] UseArraysAsList false positive with non-trivial loops
  • javascript
    • #2605: [js] Support unicode characters
    • #3948: [js] Invalid operator error for method property in object literal
  • python
    • #2604: [python] Support unicode identifiers

API Changes

Deprecated ruleset references

Ruleset references with the following formats are now deprecated and will produce a warning when used on the CLI or in a ruleset XML file:

  • <lang-name>-<ruleset-name>, eg java-basic, which resolves to rulesets/java/basic.xml
  • the internal release number, eg 600, which resolves to rulesets/releases/600.xml

Use the explicit forms of these references to be compatible with PMD 7.

Deprecated API

  • toString is now deprecated. The format of this method will remain the same until PMD 7. The deprecation is intended to steer users away from relying on this format, as it may be changed in PMD 7.
  • getInputPaths and setInputPaths are now deprecated. A new set of methods have been added, which use lists and do not rely on comma splitting.

Internal API

Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. You can identify them with the @InternalApi annotation. You’ll also get a deprecation warning.

External Contributions

  • #3961: [java] Fix #3954 - NPE in UseCollectionIsEmptyRule with record - @flyhard
  • #3964: [java] Fix #3874 - ImmutableField: fix mockito/spring false positives - @lukelukes
  • #3974: [cs] Add option to ignore C# attributes (annotations) - @maikelsteneker

Stats

  • 92 commits
  • 30 closed tickets & PRs
  • Days since last release: 28

30-April-2022 - 6.45.0

The PMD team is pleased to announce PMD 6.45.0.

This is a minor release.

Table Of Contents

New and noteworthy

PMD User Survey

Help shape the future of PMD by telling us how you use it.

Our little survey is still open in case you didn’t participate yet. Please participate in our survey at https://forms.gle/4d8r1a1RDzfixHDc7.

Thank you!

Support for HTML

This version of PMD ships a new language module to support analyzing of HTML. Support for HTML is experimental and might change without notice. The language implementation is not complete yet and the AST doesn’t look well for text nodes and comment nodes and might be changed in the future. You can write your own rules, but we don’t guarantee that the rules work with the next (minor) version of PMD without adjustments.

Please give us feedback about how practical this new language is in discussions. Please report missing features or bugs as new issues.

New rules

  • The HTML rule AvoidInlineStyles finds elements which use a style attribute. In order to help maintaining a webpage it is considered good practice to separate content and styles. Instead of inline styles one should use CSS files and classes.
    <rule ref="category/html/bestpractices.xml/AvoidInlineStyles" />
  • The HTML rule UnnecessaryTypeAttribute finds “link” and “script” elements which still have a “type” attribute. This is not necessary anymore since modern browsers automatically use CSS and JavaScript.
      <rule ref="category/html/bestpractices.xml/UnnecessaryTypeAttribute" />
  • The HTML rule UseAltAttributeForImages finds “img” elements without an “alt” attribute. An alternate text should always be provided in order to help screen readers.
      <rule ref="category/html/bestpractices.xml/UseAltAttributeForImages" />

Modified rules

  • The Java rule UnusedPrivateField has a new property ignoredFieldNames. The default ignores serialization-specific fields (eg serialVersionUID). The property can be used to ignore more fields based on their name. Note that the rule used to ignore fields named IDENT, but doesn’t anymore (add this value to the property to restore the old behaviour).

Fixed Issues

  • core
    • #3792: [core] Allow to filter violations in Report
    • #3881: [core] SARIF renderer depends on platform default encoding
    • #3882: [core] Fix AssertionError about exhaustive switch
    • #3884: [core] XML report via ant task contains XML header twice
    • #3896: [core] Fix ast-dump CLI when reading from stdin
  • doc
    • #2505: [doc] Improve side bar to show release date
  • java
    • #3068: [java] Some tests should not depend on real rules
    • #3889: [java] Catch LinkageError in UselessOverridingMethodRule
  • java-bestpractices
    • #3910: [java] UnusedPrivateField - Allow the ignored fieldnames to be configurable
    • #1185: [java] ArrayIsStoredDirectly false positive with field access
    • #1474: [java] ArrayIsStoredDirectly false positive with method call
    • #3879 [java] ArrayIsStoredDirectly reports duplicated violation
    • #3929: [java] ArrayIsStoredDirectly should report the assignment rather than formal parameter
  • java-design
    • #3603: [java] SimplifiedTernary: no violation for ‘condition ? true : false’ case
  • java-performance
    • #3867: [java] UseArraysAsList with method call
  • plsql
    • #3687: [plsql] Parsing exception EXECUTE IMMEDIATE l_sql BULK COLLECT INTO statement
    • #3706: [plsql] Parsing exception CURSOR statement with parenthesis groupings

API Changes

Experimental APIs

  • Report has two new methods which allow limited mutations of a given report:
    • Report#filterViolations creates a new report with some violations removed with a given predicate based filter.
    • Report#union can combine two reports into a single new Report.
  • net.sourceforge.pmd.util.Predicate will be replaced in PMD7 with the standard Predicate interface from java8.
  • The module pmd-html is entirely experimental right now. Anything in the package net.sourceforge.pmd.lang.html should be used cautiously.

External Contributions

  • #3883: [doc] Improve side bar by Adding Release Date - @jasonqiu98
  • #3910: [java] UnusedPrivateField - Allow the ignored fieldnames to be configurable - @laoseth
  • #3928: [plsql] Fix plsql parsing error in parenthesis groups - @LiGaOg
  • #3935: [plsql] Fix parser exception in EXECUTE IMMEDIATE BULK COLLECT #3687 - @Scrsloota
  • #3938: [java] Modify SimplifiedTernary to meet the missing case #3603 - @VoidxHoshi
  • #3943: chore: Set permissions for GitHub actions - @naveensrinivasan

Stats

  • 97 commits
  • 31 closed tickets & PRs
  • Days since last release: 33

27-March-2022 - 6.44.0

The PMD team is pleased to announce PMD 6.44.0.

This is a minor release.

Table Of Contents

New and noteworthy

PMD User Survey

Help shape the future of PMD by telling us how you use it.

Please participate in our survey at https://forms.gle/4d8r1a1RDzfixHDc7.

Thank you!

Java 18 Support

This release of PMD brings support for Java 18. There are no new standard language features.

PMD also supports JEP 420: Pattern Matching for switch (Second Preview) as a preview language feature. In order to analyze a project with PMD that uses these language features, you’ll need to enable it via the environment variable PMD_JAVA_OPTS and select the new language version 18-preview:

export PMD_JAVA_OPTS=--enable-preview
./run.sh pmd -language java -version 18-preview ...

Note: Support for Java 16 preview language features have been removed. The version “16-preview” is no longer available.

Better XML XPath support

The new rule class DomXPathRule is intended to replace usage of the XPathRule for XML rules. This rule executes the XPath query in a different way, which sticks to the XPath specification. This means the expression is interpreted the same way in PMD as in all other XPath development tools that stick to the standard. You can for instance test the expression in an online XPath editor.

Prefer using this class to define XPath rules: replace the value of the class attribute with net.sourceforge.pmd.lang.xml.rule.DomXPathRule like so:

<rule name="MyXPathRule"
      language="xml"
      message="A message"
      class="net.sourceforge.pmd.lang.xml.rule.DomXPathRule">

      <properties>
        <property name="xpath">
            <value><![CDATA[
            /a/b/c[@attr = "5"]
            ]]></value>
        </property>
        <!-- Note: the property "version" is ignored, remove it. The query is XPath 2. -->
      </properties>
</rule>

The rule is more powerful than XPathRule, as it can now handle XML namespaces, comments and processing instructions. Please refer to the Javadoc of DomXPathRule for information about the differences with XPathRule and examples.

XPathRule is still perfectly supported for all other languages, including Apex and Java.

New XPath functions

The new XPath functions pmd:startLine, pmd:endLine, pmd:startColumn, and pmd:endColumn are now available in XPath rules for all languages. They replace the node attributes @BeginLine, @EndLine and such. These attributes will be deprecated in a future release.

Please refer to the documentation of these functions for more information, including usage samples.

Note that the function pmd:endColumn returns an exclusive index, while the attribute @EndColumn is inclusive. This is for forward compatibility with PMD 7, which uses exclusive end indices.

New programmatic API

This release introduces a new programmatic API to replace the inflexible PMD class. Programmatic execution of PMD should now be done with a PMDConfiguration and a PmdAnalysis, for instance:

PMDConfiguration config = new PMDConfiguration();
config.setDefaultLanguageVersion(LanguageRegistry.findLanguageByTerseName("java").getVersion("11"));
config.setInputPaths("src/main/java");
config.prependAuxClasspath("target/classes");
config.setMinimumPriority(RulePriority.HIGH);
config.addRuleSet("rulesets/java/quickstart.xml");
config.setReportFormat("xml");
config.setReportFile("target/pmd-report.xml");

try (PmdAnalysis pmd = PmdAnalysis.create(config)) {
    // note: don't use `config` once a PmdAnalysis has been created.
    // optional: add more rulesets
    pmd.addRuleSet(pmd.newRuleSetLoader().loadFromResource("custom-ruleset.xml"));
    // optional: add more files
    pmd.files().addFile(Paths.get("src", "main", "more-java", "ExtraSource.java"));
    // optional: add more renderers
    pmd.addRenderer(renderer);

    // or just call PMD
    pmd.performAnalysis();
}

The PMD class still supports methods related to CLI execution: runPmd and main. All other members are now deprecated for removal. The CLI itself remains compatible, if you run PMD via command-line, no action is required on your part.

Fixed Issues

  • apex
    • #3817: [apex] Add designer bindings to display main attributes
  • apex-performance
    • #3773: [apex] EagerlyLoadedDescribeSObjectResult false positives with SObjectField.getDescribe()
  • core
    • #2693: [ci] Add integration tests with real open-source projects
    • #3299: [core] Deprecate system properties of PMDCommandLineInterface
  • java
    • #3809: [java] Support JDK 18
  • doc
    • #2504: [doc] Improve “Edit me on github” button
    • #3812: [doc] Documentation website table of contents broken on pages with many subheadings
  • java-design
    • #3850: [java] ImmutableField - false negative when field assigned in constructor conditionally
    • #3851: [java] ClassWithOnlyPrivateConstructorsShouldBeFinal - false negative when a compilation unit contains two class declarations
  • xml
    • #2766: [xml] XMLNS prefix is not pre-declared in xpath query
    • #3863: [xml] Make XPath rules work exactly as in the XPath spec

API Changes

Deprecated API

Experimental APIs

External Contributions

  • #3773: [apex] EagerlyLoadedDescribeSObjectResult false positives with SObjectField.getDescribe() - @filiprafalowicz
  • #3811: [doc] Improve “Edit me on github” button - @btjiong
  • #3836: [doc] Make TOC scrollable when too many subheadings - @JerritEic

Stats

  • 124 commits
  • 23 closed tickets & PRs
  • Days since last release: 29

26-February-2022 - 6.43.0

The PMD team is pleased to announce PMD 6.43.0.

This is a minor release.

Table Of Contents

New and noteworthy

Fixed Issues

  • core
    • #3427: [core] Stop printing CLI usage text when exiting due to invalid parameters
    • #3768: [core] SARIF formatter reports multiple locations when it should report multiple results
  • doc
    • #2502: [doc] Add floating table-of-contents (toc) on the right
    • #3807: [doc] Document Ant Task parameter threads
  • java
    • #3698: [java] Parsing error with try-with-resources and qualified resource
  • java-bestpractices
    • #3605: [java] SwitchStmtsShouldHaveDefault triggered when default case is present
  • java-codestyle
    • #278: [java] ConfusingTernary should treat != null as positive condition
  • java-performance
    • #3374: [java] UseStringBufferForStringAppends: Wrong example in documentation
  • misc
    • #3759: [lang-test] Upgrade dokka maven plugin to 1.4.32
  • plsql
    • #3746: [plsql] Parsing exception “Less than or equal to/Greater than or equal to” operators in DML statements

API Changes

Deprecated API

Some API deprecations were performed in core PMD classes, to improve compatibility with PMD 7.

  • Report: the constructor and other construction methods like addViolation or createReport
  • RuleContext: all constructors, getters and setters. A new set of stable methods, matching those in PMD 7, was added to replace the addViolation overloads of AbstractRule. In PMD 7, RuleContext will be the API to report violations, and it can already be used as such in PMD 6.
  • The field configuration is unused and will be removed.

Internal API

Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. You can identify them with the @InternalApi annotation. You’ll also get a deprecation warning.

Changed API

It is now forbidden to report a violation:

  • With a null node
  • With a null message
  • With a null set of format arguments (prefer a zero-length array)

Note that the message is set from the XML rule declaration, so this is only relevant if you instantiate rules manually.

RuleContext now requires setting the current rule before calling apply. This is done automatically by RuleSet#apply and such. Creating and configuring a RuleContext manually is strongly advised against, as the lifecycle of RuleContext will change drastically in PMD 7.

External Contributions

Stats

  • 49 commits
  • 22 closed tickets & PRs
  • Days since last release: 27

29-January-2022 - 6.42.0

The PMD team is pleased to announce PMD 6.42.0.

This is a minor release.

Table Of Contents

New and noteworthy

Javascript: Rhino updated to latest version 1.7.14

Rhino, the implementation of JavaScript we use for parsing JavaScript code, has been updated to the latest version 1.7.14. Now language features like template strings can be parsed. However Rhino does not support all features of the latest EcmaScript standard.

New rules

  • The new Java rule FinalParameterInAbstractMethod detects parameters that are declared as final in interfaces or abstract methods. Declaring the parameters as final is useless because the implementation may choose to not respect it.
    <rule ref="category/java/codestyle.xml/FinalParameterInAbstractMethod" />

The rule is part of the quickstart.xml ruleset.

Modified rules

  • The Apex rule ApexDoc has a new property reportProperty. If set to false (default is true if unspecified) doesn’t report missing ApexDoc comments on properties. It allows you to enforce ApexDoc comments for classes and methods without requiring them for properties.

Fixed Issues

  • core
    • #3328: [core] designer.bat errors when JAVAFX_HOME contains spaces
  • java
    • #3698: [java] Error resolving Symbol Table
  • java-bestpractices
    • #3209: [java] UnusedPrivateMethod false positive with static method and cast expression
    • #3468: [java] UnusedPrivateMethod false positive when outer class calls private static method on inner class
  • java-design
    • #3679: [java] Make FinalFieldCouldBeStatic detect constant variable
  • java-errorprone
    • #3644: [java] InvalidLogMessageFormat: false positives with logstash structured logging
    • #3686: [java] ReturnEmptyCollectionRatherThanNull - false negative with conditioned returns
    • #3701: [java] MissingStaticMethodInNonInstantiatableClass false positive with method inner classes
    • #3721: [java] ReturnEmptyCollectionRatherThanNull - false positive with stream and lambda
  • java-performance
    • #3492: [java] UselessStringValueOf: False positive when there is no initial String to append to
    • #3639: [java] UseStringBufferLength: false negative with empty string variable
    • #3712: [java] InsufficientStringBufferDeclaration false positive with StringBuilder.setLength(0)
  • javascript
    • #3703: [javascript] Error - no Node adapter class registered for XmlPropRef

API Changes

No changes.

External Contributions

Stats

  • 88 commits
  • 35 closed tickets & PRs
  • Days since last release: 62

27-November-2021 - 6.41.0

The PMD team is pleased to announce PMD 6.41.0.

This is a minor release.

Table Of Contents

New and noteworthy

GitHub Action for PMD

PMD now has its own official GitHub Action: GitHub Action for PMD. It can execute PMD with your own ruleset against your project. It creates a SARIF report which is uploaded as a build artifact. Furthermore the build can be failed based on the number of violations.

Feedback and pull requests are welcome at https://github.com/pmd/pmd-github-action.

Last release in 2021

This minor release will be the last one in 2021. The next release is scheduled to be end of January 2022.

Fixed Issues

  • core
    • #2954: Create GitHub Action for PMD
    • #3424: [core] Migrate CLI to using GNU-style long options
    • #3425: [core] Add a --version CLI option
    • #3593: [core] Ant task fails with Java17
    • #3635: [ci] Update sample projects for regression tester
  • java-bestpractices
    • #3595: [java] PrimitiveWrapperInstantiation: no violation on ‘new Boolean(val)’
    • #3613: [java] ArrayIsStoredDirectly doesn’t consider nested classes
    • #3614: [java] JUnitTestsShouldIncludeAssert doesn’t consider nested classes
    • #3618: [java] UnusedFormalParameter doesn’t consider anonymous classes
    • #3630: [java] MethodReturnsInternalArray doesn’t consider anonymous classes
  • java-design
    • #3620: [java] SingularField doesn’t consider anonymous classes defined in non-private fields
  • java-errorprone
    • #3624: [java] TestClassWithoutTestCases reports wrong classes in a file
  • java-performance
    • #3491: [java] UselessStringValueOf: False positive when valueOf(char [], int, int) is used

API Changes

Command Line Interface

The command line options for PMD and CPD now use GNU-syle long options format. E.g. instead of -rulesets the preferred usage is now --rulesets. Alternatively one can still use the short option -R. Some options also have been renamed to a more consistent casing pattern at the same time (--fail-on-violation instead of -failOnViolation). The old single-dash options are still supported but are deprecated and will be removed with PMD 7. This change makes the command line interface more consistent within PMD and also less surprising compared to other cli tools.

The changes in detail for PMD:

old option new option
-rulesets --rulesets (or -R)
-uri --uri
-dir --dir (or -d)
-filelist --file-list
-ignorelist --ignore-list
-format --format (or -f)
-debug --debug
-verbose --verbose
-help --help
-encoding --encoding
-threads --threads
-benchmark --benchmark
-stress --stress
-shortnames --short-names
-showsuppressed --show-suppressed
-suppressmarker --suppress-marker
-minimumpriority --minimum-priority
-property --property
-reportfile --report-file
-force-language --force-language
-auxclasspath --aux-classpath
-failOnViolation --fail-on-violation
--failOnViolation --fail-on-violation
-norulesetcompatibility --no-ruleset-compatibility
-cache --cache
-no-cache --no-cache

The changes in detail for CPD:

old option new option
--failOnViolation --fail-on-violation
-failOnViolation --fail-on-violation
--filelist --file-list

External Contributions

Stats

  • 80 commits
  • 23 closed tickets & PRs
  • Days since last release: 28

30-October-2021 - 6.40.0

The PMD team is pleased to announce PMD 6.40.0.

This is a minor release.

Table Of Contents

New and noteworthy

Updated Apex Support

  • The Apex language support has been bumped to version 54.0 (Spring ‘22).

New rules

    <rule ref="category/apex/performance.xml/EagerlyLoadedDescribeSObjectResult" />

Modified rules

  • The Apex rule ApexUnitTestClassShouldHaveAsserts has a new property additionalAssertMethodPattern. When specified the pattern is evaluated against each invoked method name to determine whether it represents a test assertion in addition to the standard names.

  • The Apex rule ApexDoc has a new property reportMissingDescription. If set to false (default is true if unspecified) doesn’t report an issue if the @description tag is missing. This is consistent with the ApexDoc dialect supported by derivatives such as SfApexDoc and also with analogous documentation tools for other languages, e.g., JavaDoc, ESDoc/JSDoc, etc.

  • The Apex rule ApexCRUDViolation has a couple of new properties: These allow specification of regular-expression-based patterns for additional methods that should be considered valid for pre-CRUD authorization beyond those offered by the system Apex checks and ESAPI, e.g., sirono-common’s AuthorizationUtil class. Two new properties have been added per-CRUD operation, one to specify the naming pattern for a method that authorizes that operation and another to specify the argument passed to that method that contains the SObjectType instance of the type being authorized. Here is an example of these new properties:

    <rule ref="category/apex/security.xml/ApexCRUDViolation" message="...">
      <priority>3</priority>
      <properties>
        <property name="createAuthMethodPattern" value="AuthorizationUtil\.(is|assert)(Createable|Upsertable)"/>
        <!--
         There's one of these properties for each operation, and the default value is 0 so this is technically
         superfluous, but it's included it here for example purposes.
         -->
        <property name="createAuthMethodTypeParamIndex" value="0"/>
        <property name="readAuthMethodPattern" value="AuthorizationUtil\.(is|assert)Accessible"/>
        <property name="updateAuthMethodPattern" value="AuthorizationUtil\.(is|assert)(Updateable|Upsertable)"/>
        <property name="deleteAuthMethodPattern" value="AuthorizationUtil\.(is|assert)Deletable"/>
        <property name="undeleteAuthMethodPattern" value="AuthorizationUtil\.(is|assert)Undeletable"/>
        <property name="mergeAuthMethodPattern" value="AuthorizationUtil\.(is|assert)Mergeable"/>
      </properties>
    </rule>
    
  • The Apex rule EmptyStatementBlock has two new properties:

    Setting reportEmptyPrivateNoArgConstructor to false ignores empty private no-arg constructors that are commonly used in singleton pattern implementations and utility classes in support of prescribed best practices.

    Setting reportEmptyVirtualMethod to false ignores empty virtual methods that are commonly used in abstract base classes as default no-op implementations when derived classes typically only override a subset of virtual methods.

    By default, both properties are true to not change the default behaviour of this rule.

  • The Apex rule EmptyCatchBlock has two new properties modeled after the analogous Java rule:

    The allowCommentedBlocks property, when set to true (defaults to false), ignores empty blocks containing comments, e.g.:

    try {
        doSomethingThatThrowsAnExpectedException();
        System.assert(false, 'Expected to catch an exception.');
    } catch (Exception e) {
        // Expected
    }
    

    The allowExceptionNameRegex property is a regular expression for exception variable names for which empty catch blocks should be ignored by this rule. For example, using the default property value of ^(ignored|expected)$, the following empty catch blocks will not be reported:

    try {
        doSomethingThatThrowsAnExpectedException();
        System.assert(false, 'Expected to catch an exception.');
    } catch (IllegalStateException ignored) {
    } catch (NumberFormatException expected) {
    }
    
  • The Apex rule OneDeclarationPerLine has a new property reportInForLoopInitializer: If set to false (default is true if unspecified) doesn’t report an issue for multiple declarations in a for loop’s initializer section. This is support the common idiom of one declaration for the loop variable and another for the loop bounds condition, e.g.,

    for (Integer i = 0, numIterations = computeNumIterations(); i < numIterations; i++) {
    }
    
  • The Java rule ClassNamingConventions uses a different default value of the property utilityClassPattern: This rule was detecting utility classes by default since PMD 6.3.0 and enforcing the naming convention that utility classes has to be suffixed with Util or Helper or Constants. However this turned out to be not so useful as a default configuration, as there is no standard naming convention for utility classes.

    With PMD 6.40.0, the default value of this property has been changed to [A-Z][a-zA-Z0-9]* (Pascal case), effectively disabling the special handling of utility classes. This is the same default pattern used for concrete classes.

    This means, that the feature to enforce a naming convention for utility classes is now a opt-in feature and can be enabled on demand.

    To use the old behaviour, the property needs to be configured as follows:

    <rule ref="category/java/codestyle.xml/ClassNamingConventions">
        <properties>
            <property name="utilityClassPattern" value="[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)" />
        </properties>
    </rule>
    

Fixed Issues

  • apex
    • #1089: [apex] ApexUnitTestClassShouldHaveAsserts: Test asserts in other methods not detected
    • #1090: [apex] ApexCRUDViolation: checks not detected if done in another method
    • #3532: [apex] Promote usage of consistent getDescribe() info
    • #3566: [apex] ApexDoc rule should not require “@description”
    • #3568: [apex] EmptyStatementBlock: should provide options to ignore empty private constructors and empty virtual methods
    • #3569: [apex] EmptyCatchBlock: should provide an option to ignore empty catch blocks in test methods
    • #3570: [apex] OneDeclarationPerLine: should provide an option to ignore multiple declarations in a for loop initializer
    • #3576: [apex] ApexCRUDViolation should provide an option to specify additional patterns for methods that encapsulate authorization checks
    • #3579: [apex] ApexCRUDViolation: false negative with undelete
  • java-bestpractices
    • #3542: [java] MissingOverride: False negative for enum method
  • java-codestyle
    • #1595: [java] Discuss default for utility classes in ClassNamingConventions
    • #3563: [java] The ClassNamingConventionsRule false-positive’s on the class name “Constants”
  • java-errorprone
    • #3560: [java] InvalidLogMessageFormat: False positive with message and exception in a block inside a lambda
  • java-performance
    • #2364: [java] AddEmptyString false positive in annotation value
  • java-security
    • #3368: [java] HardcodedCryptoKey false negative with variable assignments

API Changes

Experimental APIs

  • The interface ASTCommentContainer has been added to the Apex AST. It provides a way to check whether a node contains at least one comment. Currently this is only implemented for ASTCatchBlockStatement and used by the rule EmptyCatchBlock. This information is also available via XPath attribute @ContainsComment.

External Contributions

  • #3538: [apex] New rule EagerlyLoadedDescribeSObjectResult - Jonathan Wiesel
  • #3549: [java] Ignore AddEmptyString rule in annotations - Stanislav Myachenkov
  • #3561: [java] InvalidLogMessageFormat: False positive with message and exception in a block inside a lambda - Nicolas Filotto
  • #3565: [doc] Fix resource leak due to Files.walk - lujiefsi
  • #3571: [apex] Fix for #1089 - Added new configuration property additionalAssertMethodPattern to ApexUnitTestClassShouldHaveAssertsRule - Scott Wells
  • #3572: [apex] Fix for #3566 - Added new configuration property reportMissingDescription to ApexDocRule - Scott Wells
  • #3573: [apex] Fix for #3568 - Added new configuration properties reportEmptyPrivateNoArgConstructor and reportEmptyVirtualMethod to EmptyStatementBlock - Scott Wells
  • #3574: [apex] Fix for #3569 - Added new configuration properties allowCommentedBlocks and allowExceptionNameRegex to EmptyCatchBlock - Scott Wells
  • #3575: [apex] Fix for #3570 - Added new configuration property reportInForLoopInitializer to OneDeclarationPerLine - Scott Wells
  • #3577: [apex] Fix for #3576 - Added new configuration properties *AuthMethodPattern and *AuthMethodTypeParamIndex to ApexCRUDViolation rule - Scott Wells
  • #3578: [apex] ApexCRUDViolation: Documentation changes for #3576 - Scott Wells
  • #3580: [doc] Release notes updates for the changes in issue #3569 - Scott Wells
  • #3581: [apex] #3569 - Requested changes for code review feedback - Scott Wells

Stats

  • 72 commits
  • 37 closed tickets & PRs
  • Days since last release: 34

25-September-2021 - 6.39.0

The PMD team is pleased to announce PMD 6.39.0.

This is a minor release.

Table Of Contents

New and noteworthy

All Contributors

PMD follows the All Contributors specification. Contributions of any kind welcome!

See credits for our complete contributors list.

Fixed Issues

  • core
    • #3499: [core] Fix XPath rulechain with combined node tests
  • java-errorprone
    • #3493: [java] AvoidAccessibilityAlteration: add tests and fix rule
  • javascript
    • #3516: [javascript] NPE while creating rule violation when specifying explicit line numbers
  • plsql
    • #3487: [plsql] Parsing exception OPEN ref_cursor_name FOR statement
    • #3515: [plsql] Parsing exception SELECT…INTO on Associative Arrays Types

API Changes

No changes.

External Contributions

  • #3516: [javascript] NPE while creating rule violation when specifying explicit line numbers - Kevin Guerra

Stats

  • 37 commits
  • 10 closed tickets & PRs
  • Days since last release: 27

28-August-2021 - 6.38.0

The PMD team is pleased to announce PMD 6.38.0.

This is a minor release.

Table Of Contents

Fixed Issues

  • apex
    • #3462: [apex] SOQL performed in a for-each loop doesn’t trigger ApexCRUDViolationRule
    • #3484: [apex] ApexCRUDViolationRule maintains state across files
  • core
    • #3446: [core] Allow XPath rules to access the current file name
  • java-bestpractices
    • #3403: [java] MethodNamingConventions junit5TestPattern does not detect parameterized tests

External Contributions

Stats

  • 32 commits
  • 8 closed tickets & PRs
  • Days since last release: 27

31-July-2021 - 6.37.0

The PMD team is pleased to announce PMD 6.37.0.

This is a minor release.

Table Of Contents

New and noteworthy

Java 17 Support

This release of PMD brings support for Java 17. PMD supports JEP 409: Sealed Classes which has been promoted to be a standard language feature of Java 17.

PMD also supports JEP 406: Pattern Matching for switch (Preview) as a preview language feature. In order to analyze a project with PMD that uses these language features, you’ll need to enable it via the environment variable PMD_JAVA_OPTS and select the new language version 17-preview:

export PMD_JAVA_OPTS=--enable-preview
./run.sh pmd -language java -version 17-preview ...

Note: Support for Java 15 preview language features have been removed. The version “15-preview” is no longer available.

Updated PMD Designer

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

New rules

This release ships with 3 new Java rules.

    <rule ref="category/java/bestpractices.xml/PrimitiveWrapperInstantiation" />

The rule is part of the quickstart.xml ruleset.

    <rule ref="category/java/bestpractices.xml/SimplifiableTestAssertion" />

The rule is part of the quickstart.xml ruleset.

    <rule ref="category/java/errorprone.xml/ReturnEmptyCollectionRatherThanNull" />

The rule is part of the quickstart.xml ruleset.

Renamed rules

  • The Java rule MissingBreakInSwitch has been renamed to ImplicitSwitchFallThrough (category error prone) to better reflect the rule’s purpose: The rule finds implicit fall-through cases in switch statements, which are most likely unexpected. The old rule name described only one way how to avoid a fall-through, namely using break but continue, throw and return avoid a fall-through as well. This enables us to improve this rule in the future.

Deprecated rules

Fixed Issues

  • apex
    • #3201: [apex] ApexCRUDViolation doesn’t report Database class DMLs, inline no-arg object instantiations and inline list initialization
    • #3329: [apex] ApexCRUDViolation doesn’t report SOQL for loops
  • core
    • #1603: [core] Language version comparison
    • #2133: [xml] Allow to check Salesforce XML Metadata using XPath rules
    • #3377: [core] NPE when specifying report file in current directory in PMD CLI
    • #3387: [core] CPD should avoid unnecessary copies when running with –skip-lexical-errors
  • java-bestpractices
    • #2908: [java] Merge Junit assertion simplification rules
    • #3235: [java] UseTryWithResources false positive when closeable is provided as a method argument or class field
  • java-errorprone
    • #3361: [java] Rename rule MissingBreakInSwitch to ImplicitSwitchFallThrough
    • #3382: [java] New rule ReturnEmptyCollectionRatherThanNull
  • java-performance
    • #3420: [java] NPE in InefficientStringBuffering with Records

API Changes

PMD CLI

  • PMD has a new CLI option -force-language. With that a language can be forced to be used for all input files, irrespective of filenames. When using this option, the automatic language selection by extension is disabled and all files are tried to be parsed with the given language. Parsing errors are ignored and unparsable files are skipped.

    This option allows to use the xml language for files, that don’t use xml as extension. See also the examples on PMD CLI reference.

Experimental APIs

Internal API

Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. You can identify them with the @InternalApi annotation. You’ll also get a deprecation warning.

External Contributions

Stats

  • 82 commits
  • 29 closed tickets & PRs
  • Days since last release: 35

26-June-2021 - 6.36.0

The PMD team is pleased to announce PMD 6.36.0.

This is a minor release.

Table Of Contents

New and noteworthy

Improved Incremental Analysis

Incremental Analysis has long helped our users obtain faster analysis results, however, its implementation tended to be too cautious in detecting changes to the runtime and type resolution classpaths, producing more cache invalidations than necessary. We have now improved the heuristics to remove several bogus invalidations, and slightly sped up the cache usage along the way.

PMD will now ignore:

  • Non class files in classpath and jar / zip files being referenced.
  • Changes to the order of file entries within a jar / zip
  • Changes to file metadata within jar / zip (ie: creation and modification time, significant in multi-module / composite build projects where lateral artifacts are frequently recreated)

New rules

  • The new Apex rule AvoidDebugStatements finds usages of System.debug calls. Debug statements contribute to longer transactions and consume Apex CPU time even when debug logs are not being captured. You can try out this rule like so:
    <rule ref="category/apex/performance.xml/AvoidDebugStatements" />
  • The new Apex rule InaccessibleAuraEnabledGetter checks that an AuraEnabled getter is public or global. This is necessary if it is referenced in Lightning components. You can try out this rule like so:
    <rule ref="category/apex/errorprone.xml/InaccessibleAuraEnabledGetter" />

Renamed rules

  • The Java rule BadComparison has been renamed to ComparisonWithNaN to better reflect what the rule actually detects. It now considers usages of Double.NaN or Float.NaN in more cases and fixes false negatives.

Fixed Issues

  • apex
    • #3307: [apex] Avoid debug statements since it impact performance
    • #3321: [apex] New rule to detect inaccessible AuraEnabled getters (summer ‘21 security update)
    • #3332: [apex] CognitiveComplexity - incorrect increment for “else if”
  • core
    • #2637: [cpd] Error Loading stylesheet cpdhtml.xslt
    • #3323: [core] Adds fullDescription and tags in SARIF report
  • java-bestpractices
    • #957: [java] GuardLogStatement: False positive with compile-time constant arguments
    • #3076: [java] UnusedAssignment reports unused variable when used in increment expr
    • #3114: [java] UnusedAssignment false positive when reporting unused variables
    • #3315: [java] LiteralsFirstInComparisons false positive with two constants
    • #3341: [java] JUnitTestsShouldIncludeAssert should support Junit 5
    • #3340: [java] NullPointerException applying rule GuardLogStatement
  • java-codestyle
    • #3317: [java] Update UnnecessaryImport to recognize usage of imported types in javadoc’s @exception tag
  • java-errorprone
    • #2895: [java] Improve BadComparison and rename to ComparisonWithNaN
    • #3284: [java] InvalidLogMessageFormat may examine the value of a different but identically named String variable
    • #3304: [java] NPE in MoreThanOneLoggerRule on a java 16 record
    • #3305: [java] ConstructorCallsOverridableMethodRule IndexOutOfBoundsException on a java16 record
    • #3343: [java] CloneMethodMustImplementCloneable: FN with local classes
  • java-performance
    • #3331: [java] UseArraysAsList false negative with for-each loop
    • #3344: [java] InefficientEmptyStringCheck FN with trim.length on method call

API Changes

No changes.

External Contributions

  • #3276: [apex] Update ApexCRUDViolation and OperationWithLimitsInLoop docs - Jonathan Wiesel
  • #3306: [java] More than one logger rule test null pointer exception - Arnaud Jeansen
  • #3317: [java] Update UnnecessaryImport to recognize usage of imported types in javadoc’s @exception tag - Piotrek Żygieło
  • #3319: [apex] New AvoidDebugStatements rule to mitigate performance impact - Jonathan Wiesel
  • #3320: [java] Fix incorrect increment for “else if” branch in Cognitive Complexity docs - Denis Borovikov
  • #3322: [apex] added rule to detect inaccessible AuraEnabled getters - Philippe Ozil
  • #3323: [core] Adds fullDescription and tags in SARIF report - Clint Chester
  • #3339: [java] JUnitTestsShouldIncludeAssert Tweak assertion definition to avoid false positive with modern JUnit5 - Arnaud Jeansen

Stats

  • 81 commits
  • 36 closed tickets & PRs
  • Days since last release: 28

29-May-2021 - 6.35.0

The PMD team is pleased to announce PMD 6.35.0.

This is a minor release.

Table Of Contents

New and noteworthy

Javascript module now requires at least Java 8

The latest version of Rhino, the implementation of JavaScript we use for parsing JavaScript code, requires at least Java 8. Therefore we decided to upgrade the pmd-javascript module to Java 8 as well. This means that from now on, a Java 8 or later runtime is required in order to analyze JavaScript code. Note that PMD core still only requires Java 7.

New rules

This release ships with 3 new Java rules.

  • JUnit5TestShouldBePackagePrivate enforces the convention that JUnit 5 tests should have minimal visibility. You can try out this rule like so:
    <rule ref="category/java/bestpractices.xml/JUnit5TestShouldBePackagePrivate" />
    
  • CognitiveComplexity uses the cognitive complexity metric to find overly complex code. This metric improves on the similar cyclomatic complexity in several ways, for instance, it incentivizes using clearly readable shorthands and idioms. See the rule documentation for more details. You can try out this rule like so:
    <rule ref="category/java/design.xml/CognitiveComplexity" />
    
  • MutableStaticState finds non-private static fields that are not final. These fields break encapsulation since these fields can be modified from anywhere within the program. You can try out this rule like so:
    <rule ref="category/java/design.xml/MutableStaticState" />
    

Modified rules

  • The Java rule CompareObjectsWithEquals has now a new property typesThatCompareByReference. With that property, you can configure types, that should be whitelisted for comparison by reference. By default, java.lang.Enum and java.lang.Class are allowed, but you could add custom types here. Additionally comparisons against constants are allowed now. This makes the rule less noisy when two constants are compared. Constants are identified by looking for an all-caps identifier.

Deprecated rules

  • The java rule DefaultPackage has been deprecated in favor of CommentDefaultAccessModifier.

    The rule “DefaultPackage” assumes that any usage of package-access is accidental, and by doing so, prohibits using a really fundamental and useful feature of the language.

    To satisfy the rule, you have to make the member public even if it doesn’t need to, or make it protected, which muddies your intent even more if you don’t intend the class to be extended, and may be at odds with other rules like AvoidProtectedFieldInFinalClass.

    The rule CommentDefaultAccessModifier should be used instead. It flags the same thing, but has an escape hatch.

  • The Java rule CloneThrowsCloneNotSupportedException has been deprecated without replacement.

    The rule has no real value as CloneNotSupportedException is a checked exception and therefore you need to deal with it while implementing the clone() method. You either need to declare the exception or catch it. If you catch it, then subclasses can’t throw it themselves explicitly. However, Object.clone() will still throw this exception if the Cloneable interface is not implemented.

    Note, this rule has also been removed from the Quickstart Ruleset (rulesets/java/quickstart.xml).

Fixed Issues

  • apex
    • #3183: [apex] ApexUnitTestMethodShouldHaveIsTestAnnotation false positive with helper method
    • #3243: [apex] Correct findBoundary when traversing AST
  • core
    • #2639: [core] PMD CLI output file is not created if directory or directories in path don’t exist
    • #3196: [core] Deprecate ThreadSafeReportListener
  • doc
    • #3230: [doc] Remove “Edit me” button for language index pages
  • dist
    • #2466: [dist] Distribution archive doesn’t include all batch scripts
  • java
    • #3269: [java] Fix NPE in MethodTypeResolution
  • java-bestpractices
    • #1175: [java] UnusedPrivateMethod FP with Junit 5 @MethodSource
    • #2219: [java] Document Reasons to Avoid Reassigning Parameters
    • #2737: [java] Fix misleading rule message on rule SwitchStmtsShouldHaveDefault with non-exhaustive enum switch
    • #3236: [java] LiteralsFirstInComparisons should consider constant fields (cont’d)
    • #3239: [java] PMD could enforce non-public methods for Junit5 / Jupiter test methods
    • #3254: [java] AvoidReassigningParameters reports violations on wrong line numbers
  • java-codestyle
    • #2655: [java] UnnecessaryImport false positive for on-demand imports
    • #3206: [java] Deprecate rule DefaultPackage
    • #3262: [java] FieldDeclarationsShouldBeAtStartOfClass: false negative with anon classes
    • #3265: [java] MethodArgumentCouldBeFinal: false negatives with interfaces and inner classes
    • #3266: [java] LocalVariableCouldBeFinal: false negatives with interfaces, anon classes
    • #3274: [java] OnlyOneReturn: false negative with anonymous class
    • #3275: [java] UnnecessaryLocalBeforeReturn: false negatives with lambda and anon class
  • java-design
    • #2780: [java] DataClass example from documentation results in false-negative
    • #2987: [java] New Rule: Public and protected static fields must be final
    • #2329: [java] Cognitive complexity rule for Java
  • java-errorprone
    • #3110: [java] Enhance CompareObjectsWithEquals with list of exceptions
    • #3112: [java] Deprecate rule CloneThrowsCloneNotSupportedException
    • #3205: [java] Make CompareObjectWithEquals allow comparing against constants
    • #3248: [java] Documentation is wrong for SingletonClassReturningNewInstance rule
    • #3249: [java] AvoidFieldNameMatchingTypeName: False negative with interfaces
    • #3268: [java] ConstructorCallsOverridableMethod: IndexOutOfBoundsException with annotations
  • java-performance
    • #1438: [java] InsufficientStringBufferDeclaration false positive for initial calculated StringBuilder size
  • javascript
    • #699: [javascript] Update Rhino library to 1.7.13
    • #2081: [javascript] Failing with OutOfMemoryError parsing a Javascript file

API Changes

Deprecated API

External Contributions

Stats

  • 143 commits
  • 53 closed tickets & PRs
  • Days since last release: 34

24-April-2021 - 6.34.0

The PMD team is pleased to announce PMD 6.34.0.

This is a minor release.

Table Of Contents

New and noteworthy

New rules

Modified rules

  • The Apex rule ApexCRUDViolation does not ignore getters anymore and also flags SOQL/SOSL/DML operations without access permission checks in getters. This will produce false positives now for VF getter methods, but we can’t reliably detect, whether a getter is a VF getter or not. In such cases, the violation should be suppressed.

Deprecated rules

Fixed Issues

  • apex-performance
    • #3198: [apex] OperationWithLimitsInLoopRule: Support more limit consuming static method invocations
  • apex-security
    • #3202: [apex] ApexCRUDViolationRule fails to report CRUD violation on COUNT() queries
    • #3210: [apex] ApexCRUDViolationRule false-negative on non-VF getter
  • java-bestpractices
    • #3190: [java] Use StandardCharsets instead of Charset.forName
    • #3224: [java] UnusedAssignment crashes with nested records
  • java-codestyle
    • #3128: [java] New rule UnnecessaryImport, deprecate DuplicateImports, ImportFromSamePackage, UnusedImports
  • java-errorprone
    • #2757: [java] CloseResource: support Lombok’s @Cleanup annotation
    • #3169: [java] CheckSkipResult: NPE when using pattern bindings

API Changes

No changes.

External Contributions

  • #3193: [java] New rule: UseStandardCharsets - Andrea Aime
  • #3198: [apex] OperationWithLimitsInLoopRule: Support more limit consuming static method invocations - Jonathan Wiesel
  • #3211: [apex] ApexCRUDViolationRule: Do not assume method is VF getter to avoid CRUD checks - Jonathan Wiesel
  • #3234: [apex] ApexCRUDViolation: COUNT is indeed CRUD checkable since it exposes data (false-negative) - Jonathan Wiesel

Stats

  • 74 commits
  • 18 closed tickets & PRs
  • Days since last release: 27

27-March-2021 - 6.33.0

The PMD team is pleased to announce PMD 6.33.0.

This is a minor release.

Table Of Contents

New and noteworthy

PLSQL parsing exclusions

The PMD PLSQL parser might not parse every valid PL/SQL code without problems. In order to still use PMD on such files, you can now mark certain lines for exclusion from the parser. More information can be found in the language specific documentation for PLSQL.

Fixed Issues

  • apex-design
    • #3142: [apex] ExcessiveClassLength multiple warning on the same class
  • java
    • #3117: [java] Infinite loop when parsing invalid code nested in lambdas
    • #3145: [java] Parse exception when using “record” as variable name
  • java-bestpractices
    • #3118: [java] UnusedPrivateMethod false positive when passing in lombok.val as argument
    • #3144: [java] GuardLogStatement can have more detailed example
    • #3155: [java] GuardLogStatement: False negative with unguarded method call
    • #3160: [java] MethodReturnsInternalArray does not consider static final fields and fields initialized with empty array
  • java-errorprone
    • #2977: [java] CloseResource: false positive with reassignment detection
    • #3146: [java] InvalidLogMessageFormat detection failing when String.format used
    • #3148: [java] CloseResource false positive with Objects.nonNull
    • #3165: [java] InvalidLogMessageFormat detection failing when String.format used in a variable
  • java-performance
    • #2427: [java] ConsecutiveLiteralAppend false-positive with builder inside lambda
    • #3152: [java] ConsecutiveLiteralAppends and InsufficientStringBufferDeclaration: FP with switch expressions
  • plsql
    • #195: [plsql] Ampersand ‘&’ causes PMD processing error in sql file - Lexical error in file

External Contributions

  • #3161: [plsql] Add support for lexical parameters in SQL*Plus scripts, allow excluding lines which the parser does not understand - Henning von Bargen
  • #3167: [java] Minor typo in quickstart ruleset - Austin Tice

Stats

  • 49 commits
  • 27 closed tickets & PRs
  • Days since last release: 28

27-February-2021 - 6.32.0

The PMD team is pleased to announce PMD 6.32.0.

This is a minor release.

Table Of Contents

New and noteworthy

Java 16 Support

This release of PMD brings support for Java 16. PMD supports JEP 394: Pattern Matching for instanceof and JEP 395: Records. Both have been promoted to be a standard language feature of Java 16.

PMD also supports JEP 397: Sealed Classes (Second Preview) as a preview language feature. In order to analyze a project with PMD that uses these language features, you’ll need to enable it via the environment variable PMD_JAVA_OPTS and select the new language version 16-preview:

export PMD_JAVA_OPTS=--enable-preview
./run.sh pmd -language java -version 16-preview ...

Note: Support for Java 14 preview language features have been removed. The version “14-preview” is no longer available.

Modified Rules

  • The Apex rule ApexDoc has two new properties: reportPrivate and reportProtected. Previously the rule only considered public and global classes, methods, and properties. With these properties, you can verify the existence of ApexDoc comments for private and protected methods as well. By default, these properties are disabled to preserve backwards compatible behavior.

Fixed Issues

  • apex-documentation
    • #3075: [apex] ApexDoc should support private access modifier
  • java
    • #3101: [java] NullPointerException when running PMD under JRE 11
  • java-bestpractices
    • #3132: [java] UnusedImports with static imports on subclasses
  • java-errorprone
    • #2716: [java] CompareObjectsWithEqualsRule: False positive with Enums
    • #3089: [java] CloseResource rule throws exception on spaces in property types
    • #3133: [java] InvalidLogMessageFormat FP with StringFormattedMessage and ParameterizedMessage
  • plsql
    • #3106: [plsql] ParseException while parsing EXECUTE IMMEDIATE ‘drop database link ‘ || linkname;

API Changes

Experimental APIs

Internal API

Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. You can identify them with the @InternalApi annotation. You’ll also get a deprecation warning.

  • The protected or public member of the Java rule AvoidUsingHardCodedIPRule are deprecated and considered to be internal API. They will be removed with PMD 7.

External Contributions

Stats

  • 43 commits
  • 21 closed tickets & PRs
  • Days since last release: 27

30-January-2021 - 6.31.0

The PMD team is pleased to announce PMD 6.31.0.

This is a minor release.

Table Of Contents

New and noteworthy

SARIF Format

PMD now supports the Static Analysis Results Interchange Format (SARIF) as an additional report format. Just use the command line parameter -format sarif to select it. SARIF is an OASIS standard format for static analysis tools. PMD creates SARIF JSON files in SARIF version 2.1.0. An example report can be found in the documentation in Report formats for PMD.

CPD

  • The C++ module now supports the new option --ignore-literal-sequences, which can be used to avoid detection of some uninteresting clones. This options has been introduced with PMD 6.30.0 for C# and is now available for C++ as well. See #2963.

New Rules

  • The new Apex rule OverrideBothEqualsAndHashcode brings the well known Java rule to Apex. In Apex the same principle applies: equals and hashCode should always be overridden together to ensure collection classes such as Maps and Sets work as expected.

  • The new Visualforce rule VfHtmlStyleTagXss checks for potential XSS problems when using <style> tags on Visualforce pages.

Deprecated rules

  • java-performance
    • AvoidUsingShortType: arithmetic on shorts is not significantly slower than on ints, whereas using shorts may provide significant memory savings in arrays.
    • SimplifyStartsWith: the suggested code transformation has an insignificant performance impact, and decreases readability.

Fixed Issues

  • core
    • #2953: [core] Support SARIF JSON Format
    • #2970: [core] PMD 6.30.0 release is not reproducible
    • #2994: [core] Fix code climate severity strings
  • java-bestpractices
    • #575: [java] LiteralsFirstInComparisons should consider constant fields
    • #2454: [java] UnusedPrivateMethod violation for disabled class in 6.23.0
    • #2833: [java] NPE in UseCollectionIsEmptyRule with enums
    • #2876: [java] UnusedPrivateField cannot override ignored annotations property
    • #2957: [java] Ignore unused declarations that have special name
  • java-codestyle
    • #2960: [java] Thread issue in MethodNamingConventionsRule
  • java-design
    • #3006: [java] NPE in SingularFieldRule with concise resource syntax
  • java-errorprone
    • #2976: [java] CompareObjectsWithEquals: FP with array.length
    • #2977: [java] 6.30.0 introduces new false positive in CloseResource rule?
    • #2979: [java] UseEqualsToCompareStrings: FP with “var” variables
    • #3004: [java] UseEqualsToCompareStrings false positive with PMD 6.30.0
    • #3062: [java] CloseResource FP with reassigned stream
  • java-performance
    • #2296: [java] Deprecate rule AvoidUsingShortType
    • #2740: [java] Deprecate rule SimplifyStartsWith
    • #3088: [java] AvoidInstantiatingObjectsInLoops - false positive with Collections
  • vf-security
    • #3081: [vf] VfUnescapeEl: Inherently un-XSS-able built-in functions trigger false positives

API Changes

Deprecated API

Experimental APIs

  • The method GenericToken#getKind has been added as experimental. This unifies the token interface for both JavaCC and Antlr. The already existing method AntlrToken#getKind is therefore experimental as well. The returned constant depends on the actual language and might change whenever the grammar of the language is changed.

External Contributions

Stats

  • 116 commits
  • 40 closed tickets & PRs
  • Days since last release: 49

12-December-2020 - 6.30.0

The PMD team is pleased to announce PMD 6.30.0.

This is a minor release.

Table Of Contents

New and noteworthy

CPD
  • The C# module now supports the new option --ignore-literal-sequences, which can be used to avoid detection of some uninteresting clones. Support for other languages may be added in the future. See #2945

  • The Scala module now supports suppression through CPD-ON/CPD-OFF comment pairs. See #2929

Type information for VisualForce

The Visualforce AST now can resolve the data type of Visualforce expressions that reference Apex Controller properties and Custom Object fields. This feature improves the precision of existing rules, like VfUnescapeEl.

This can be configured using two environment variables:

  • PMD_VF_APEXDIRECTORIES: Comma separated list of directories for Apex classes. Absolute or relative to the Visualforce directory. Default is ../classes. Specifying an empty string will disable data type resolution for Apex Controller properties.
  • PMD_VF_OBJECTSDIRECTORIES: Comma separated list of directories for Custom Objects. Absolute or relative to the Visualforce directory. Default is ../objects. Specifying an empty string will disable data type resolution for Custom Object fields.

This feature is experimental, in particular, expect changes to the way the configuration is specified. We’ll probably extend the CLI instead of relying on environment variables in a future version.

Thanks to Jeff Bartolotta and Roopa Mohan for contributing this!

Fixed Issues

  • core
    • #1939: [core] XPath expressions return handling
    • #1961: [core] Text renderer should include name of violated rule
    • #2874: [core] Fix XMLRenderer with UTF-16
  • cs
    • #2938: [cs] CPD: ignoring using directives could not be disabled
  • java
    • #2911: [java] ClassTypeResolver#searchNodeNameForClass leaks memory
    • #2934: [java] CompareObjectsWithEquals / UseEqualsToCompareStrings - False negatives with fields
    • #2940: [java] Catch additional TypeNotPresentExceptions / LinkageErrors
  • scala
    • #2480: [scala] Support CPD suppressions

API Changes

Deprecated API

Around RuleSet parsing
Around the PMD class

Many classes around PMD’s entry point (PMD) have been deprecated as internal, including:

Miscellaneous

Internal API

Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. You can identify them with the @InternalApi annotation. You’ll also get a deprecation warning.

External Contributions

Stats

  • 190 commits
  • 25 closed tickets & PRs
  • Days since last release: 49

24-October-2020 - 6.29.0

The PMD team is pleased to announce PMD 6.29.0.

This is a minor release.

Table Of Contents

New and noteworthy

Updated Apex Support

New Rules

  • The new Apex rule OperationWithLimitsInLoop (apex-performance) finds operations in loops that may hit governor limits such as DML operations, SOQL queries and more. The rule replaces the three rules “AvoidDmlStatementsInLoops”, “AvoidSoqlInLoops”, and “AvoidSoslInLoops”.

Renamed Rules

  • The Java rule DoNotCallSystemExit has been renamed to DoNotTerminateVM, since it checks for all the following calls: System.exit(int), Runtime.exit(int), Runtime.halt(int). All these calls terminate the Java VM, which is bad, if the VM runs an application server which many independent applications.

Deprecated Rules

Fixed Issues

  • apex
    • #2839: [apex] Apex classes with safe navigation operator from Winter 21 (50.0) are skipped
  • apex-performance
    • #1713: [apex] Mark Database DML statements in For Loop
  • core
    • #2831: [core] Fix XMLRenderer newlines when running under IBM Java
  • java-errorprone
    • #2157: [java] Improve DoNotCallSystemExit: permit call in main(), flag System.halt
    • #2764: [java] CloseResourceRule does not recognize multiple assignment done to resource
  • miscellaneous
    • #2823: [doc] Renamed/Moved rules are missing in documentation
  • vf (Salesforce VisualForce)
    • #2765: [vf] Attributes with dot cause a VfParseException

External Contributions

Stats

  • 50 commits
  • 23 closed tickets & PRs
  • Days since last release: 27

26-September-2020 - 6.28.0

The PMD team is pleased to announce PMD 6.28.0.

This is a minor release.

Table Of Contents

New and noteworthy

CPD’s AnyTokenizer has been improved

The AnyTokenizer is used for languages, that don’t have an own lexer/grammar based tokenizer. AnyTokenizer now handles string literals and end-of-line comments. Fortran, Perl and Ruby have been updated to use AnyTokenizer instead of their old custom tokenizer based on AbstractTokenizer. See #2758 for details.

AbstractTokenizer and the custom tokenizers of Fortran, Perl and Ruby are deprecated now.

Fixed Issues

  • cpd
    • #2758: [cpd] Improve AnyTokenizer
    • #2760: [cpd] AnyTokenizer doesn’t count columns correctly
  • apex-security
    • #2774: [apex] ApexSharingViolations does not correlate sharing settings with class that contains data access
  • java
    • #2738: [java] Custom rule with @ExhaustiveEnumSwitch throws NPE
    • #2755: [java] [6.27.0] Exception applying rule CloseResource on file … java.lang.NullPointerException
    • #2756: [java] TypeTestUtil fails with NPE for anonymous class
    • #2767: [java] IndexOutOfBoundsException when parsing an initializer BlockStatement
    • #2783: [java] Error while parsing with lambda of custom interface
  • java-bestpractices
    • #2759: [java] False positive in UnusedAssignment
  • java-design
    • #2708: [java] False positive FinalFieldCouldBeStatic when using lombok Builder.Default

API Changes

Deprecated API

For removal

External Contributions

  • #2735: [ci] Add github actions for a fast view of pr succeed/not - XenoAmess
  • #2747: [java] Don’t trigger FinalFieldCouldBeStatic when field is annotated with lombok @Builder.Default - Ollie Abbey
  • #2773: [java] issue-2738: Adding null check to avoid npe when switch case is default - Nimit Patel
  • #2789: Add badge for reproducible build - Dan Rollo
  • #2791: [apex] Analyze inner classes for sharing violations - Jeff Bartolotta

Stats

  • 58 commits
  • 24 closed tickets & PRs
  • Days since last release: 25

31-August-2020 - 6.27.0

The PMD team is pleased to announce PMD 6.27.0.

This is a minor release.

Table Of Contents

New and noteworthy

Java 15 Support

This release of PMD brings support for Java 15. PMD can parse Text Blocks which have been promoted to be a standard language feature of Java.

PMD also supports Pattern Matching for instanceof, Records, and Sealed Classes.

Note: The Pattern Matching for instanceof, Records, and Sealed Classes are all preview language features of OpenJDK 15 and are not enabled by default. In order to analyze a project with PMD that uses these language features, you’ll need to enable it via the environment variable PMD_JAVA_OPTS and select the new language version 15-preview:

export PMD_JAVA_OPTS=--enable-preview
./run.sh pmd -language java -version 15-preview ...

Note: Support for Java 13 preview language features have been removed. The version “13-preview” is no longer available.

Changes in how tab characters are handled

In the past, tab characters in source files has been handled differently in different languages by PMD. For instance in Java, tab characters had a width of 8 columns, while C# used only 1 column. Visualforce instead used 4 columns.

This has been unified now so that tab characters are consistently now always 1 column wide.

This however might be a incompatible change, if you’re using the properties “BeginColumn” or “EndColumn” additionally to “BeginLine” and “EndLine” of a Token/AST node in order to highlight where a rule violation occurred in the source file. If you have logic there that deals with tab characters, you most likely can remove this logic now, since tab characters are now just “normal” characters in terms of string processing.

See also [all] Ensure PMD/CPD uses tab width of 1 for tabs consistently #2656.

Updated PMD Designer

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

New Rules

  • The new Java rule AvoidReassigningCatchVariables (java-bestpractices) finds cases where the variable of the caught exception is reassigned. This practice is surprising and prevents further evolution of the code like multi-catch.

Modified Rules

  • The Java rule CloseResource (java-errorprone) has a new property closeNotInFinally. With this property set to true the rule will also find calls to close a resource, which are not in a finally-block of a try-statement. If a resource is not closed within a finally block, it might not be closed at all in case of exceptions.

    As this new detection would yield many new violations, it is disabled by default. It might be enabled in a later version of PMD.

Deprecated Rules

Fixed Issues

  • core
    • #724: [core] Avoid parsing rulesets multiple times
    • #1962: [core] Simplify Report API
    • #2653: [lang-test] Upgrade kotlintest to Kotest
    • #2656: [all] Ensure PMD/CPD uses tab width of 1 for tabs consistently
    • #2690: [core] Fix java7 compatibility
  • java
    • #2646: [java] Support JDK 15
  • java-bestpractices
    • #2471: [java] New Rule: AvoidReassigningCatchVariables
    • #2663: [java] NoClassDefFoundError on upgrade from 6.25.0 to 6.26.0
    • #2668: [java] UnusedAssignment false positives
    • #2673: [java] UnusedPrivateField and SingularField false positive with lombok annotation EqualsAndHashCode
    • #2684: [java] UnusedAssignment FP in try/catch
    • #2686: [java] UnusedAssignment must not flag abstract method parameters in interfaces and abstract classes
  • java-design
    • #2108: [java] [doc] ImmutableField rule: Description should clarify shallow immutability
    • #2461: [java] ExcessiveParameterListRule must ignore a private constructor
  • java-errorprone
    • #2264: [java] SuspiciousEqualsMethodName: Improve description about error-prone overloading of equals()
    • #2410: [java] ProperCloneImplementation not valid for final class
    • #2431: [java] InvalidLogMessageFormatRule throws IndexOutOfBoundsException when only logging exception message
    • #2439: [java] AvoidCatchingThrowable can not detect the case: catch (java.lang.Throwable t)
    • #2470: [java] CloseResource false positive when resource included in return value
    • #2531: [java] UnnecessaryCaseChange can not detect the case like: foo.equals(bar.toLowerCase())
    • #2647: [java] Deprecate rule DataFlowAnomalyAnalysis
  • java-performance
    • #1868: [java] false-positive for SimplifyStartsWith if string is empty
    • #2441: [java] RedundantFieldInitializer can not detect a special case for char initialize: char foo = '\0';
    • #2530: [java] StringToString can not detect the case: getStringMethod().toString()
  • dart
    • #2750: [dart] [cpd] Cpd Dart escaped dollar

API Changes

  • XML rule definition in rulesets: In PMD 7, the language attribute will be required on all rule elements that declare a new rule. Some base rule classes set the language implicitly in their constructor, and so this is not required in all cases for the rule to work. But this behavior will be discontinued in PMD 7, so missing language attributes are now reported as a forward compatibility warning.

Deprecated API

For removal

External Contributions

Stats

  • 189 commits
  • 68 closed tickets & PRs
  • Days since last release: 37

25-July-2020 - 6.26.0

The PMD team is pleased to announce PMD 6.26.0.

This is a minor release.

Table Of Contents

New and noteworthy

New Rules

  • The new Java rule UnusedAssignment (java-bestpractices) finds assignments to variables, that are never used and are useless. The new rule is supposed to entirely replace DataflowAnomalyAnalysis.

Modified rules

  • The Java rule ArrayIsStoredDirectly (java-bestpractices) now ignores by default private methods and constructors. You can restore the old behavior by setting the new property allowPrivate to “false”.

Fixed Issues

  • apex
    • #2610: [apex] Support top-level enums in rules
  • apex-bestpractices
    • #2626: [apex] UnusedLocalVariable - false positive on case insensitivity allowed in Apex
  • apex-performance
    • #2598: [apex] AvoidSoqlInLoops false positive for SOQL with in For-Loop
  • apex-security
    • #2620: [visualforce] False positive on VfUnescapeEl with new Message Channel feature
  • core
    • #710: [core] Review used dependencies
    • #2594: [core] Update exec-maven-plugin and align it in all project
    • #2615: [core] PMD/CPD produces invalid XML (insufficient escaping/wrong encoding)
  • java-bestpractices
    • #2543: [java] UseCollectionIsEmpty can not detect the case this.foo.size()
    • #2569: [java] LiteralsFirstInComparisons: False negative for methods returning Strings
    • #2622: [java] ArrayIsStoredDirectly false positive with private constructor/methods
  • java-codestyle
    • #2546: [java] DuplicateImports reported for the same import… and import static…
  • java-design
    • #2174: [java] LawOfDemeter: False positive with ‘this’ pointer
    • #2181: [java] LawOfDemeter: False positive with indexed array access
    • #2189: [java] LawOfDemeter: False positive when casting to derived class
    • #2580: [java] AvoidThrowingNullPointerException marks all NullPointerException objects as wrong, whether or not thrown
    • #2625: [java] NPathComplexity can’t handle switch expressions
  • java-errorprone
    • #2578: [java] AvoidCallingFinalize detects some false positives
    • #2634: [java] NullPointerException in rule ProperCloneImplementation
  • java-performance
    • #1736: [java] UseStringBufferForStringAppends: False positive if only one concatenation
    • #2207: [java] AvoidInstantiatingObjectsInLoops: False positive - should not flag objects when assigned to lists/arrays

API Changes

Deprecated API

For removal

External Contributions

Stats

  • 156 commits
  • 43 closed tickets & PRs
  • Days since last release: 28

27-June-2020 - 6.25.0

The PMD team is pleased to announce PMD 6.25.0.

This is a minor release.

Table Of Contents

New and noteworthy

Scala cross compilation

Up until now the PMD Scala module has been compiled against scala 2.13 only by default. However, this makes it impossible to use pmd as a library in scala projects, that use scala 2.12, e.g. in sbt plugins. Therefore PMD now provides cross compiled pmd-scala modules for both versions: scala 2.12 and scala 2.13.

The new modules have new maven artifactIds. The old artifactId net.sourceforge.pmd:pmd-scala:6.25.0 is still available, but is deprecated from now on. It has been demoted to be just a delegation to the new pmd-scala_2.13 module and will be removed eventually.

The coordinates for the new modules are:

<dependency>
    <groupId>net.sourceforge.pmd</groupId>
    <artifactId>pmd-scala_2.12</artifactId>
    <version>6.25.0</version>
</dependency>

<dependency>
    <groupId>net.sourceforge.pmd</groupId>
    <artifactId>pmd-scala_2.13</artifactId>
    <version>6.25.0</version>
</dependency>

The command line version of PMD continues to use scala 2.13.

New Rules

  • The new Java Rule UnnecessaryCast (java-codestyle) finds casts that are unnecessary while accessing collection elements.

  • The new Java Rule AvoidCalendarDateCreation (java-performance) finds usages of java.util.Calendar whose purpose is just to get the current date. This can be done in a more lightweight way.

  • The new Java Rule UseIOStreamsWithApacheCommonsFileItem (java-performance) finds usage of FileItem.get() and FileItem.getString(). These two methods are problematic since they load the whole uploaded file into memory.

Modified rules

  • The Java rule UseDiamondOperator (java-codestyle) now by default finds unnecessary usages of type parameters, which are nested, involve wildcards and are used within a ternary operator. These usages are usually only unnecessary with Java8 and later, when the type inference in Java has been improved.

    In order to avoid false positives when checking Java7 only code, the rule has the new property java7Compatibility, which is disabled by default. Settings this to “true” retains the old rule behaviour.

Fixed Issues

  • apex-bestpractices
    • #2554: [apex] Exception applying rule UnusedLocalVariable on trigger
  • core
    • #971: [apex][plsql][java] Deprecate overly specific base rule classes
    • #2451: [core] Deprecate support for List attributes with XPath 2.0
    • #2599: [core] Fix XPath 2.0 Rule Chain Analyzer with Unions
    • #2483: [lang-test] Support cpd tests based on text comparison. For details see Testing your implementation in the developer documentation.
  • c#
    • #2551: [c#] CPD suppression with comments doesn’t work
  • cpp
    • #1757: [cpp] Support unicode characters
  • java
    • #2549: [java] Auxclasspath in PMD CLI does not support relative file path
  • java-codestyle
    • #2545: [java] UseDiamondOperator false negatives
    • #2573: [java] DefaultPackage: Allow package default JUnit 5 Test methods
  • java-design
    • #2563: [java] UselessOverridingMethod false negative with already public methods
    • #2570: [java] NPathComplexity should mention the expected NPath complexity
  • java-errorprone
    • #2544: [java] UseProperClassLoader can not detect the case with method call on intermediate variable
  • java-performance
    • #2591: [java] InefficientStringBuffering/AppendCharacterWithChar: Fix false negatives with concats in appends
    • #2600: [java] UseStringBufferForStringAppends: fix false negative with fields
  • scala
    • #2547: [scala] Add cross compilation for scala 2.12 and 2.13

API Changes

  • The maven module net.sourceforge.pmd:pmd-scala is deprecated. Use net.sourceforge.pmd:pmd-scala_2.13 or net.sourceforge.pmd:pmd-scala_2.12 instead.

  • Rule implementation classes are internal API and should not be used by clients directly. The rules should only be referenced via their entry in the corresponding category ruleset (e.g. <rule ref="category/java/bestpractices.xml/AbstractClassWithoutAbstractMethod" />).

    While we definitely won’t move or rename the rule classes in PMD 6.x, we might consider changes in PMD 7.0.0 and onwards.

Deprecated APIs

Internal API

Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. You can identify them with the @InternalApi annotation. You’ll also get a deprecation warning.

For removal

External Contributions

Stats

  • 135 commits
  • 31 closed tickets & PRs
  • Days since last release: 33

24-May-2020 - 6.24.0

The PMD team is pleased to announce PMD 6.24.0.

This is a minor release.

Table Of Contents

New and noteworthy

CPD now supports XML as well

Thanks to Fernando Cosso CPD can now find duplicates in XML files as well. This is useful to find duplicated sections in XML files.

Updated PMD Designer

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

New Rules

  • The new Java Rule LiteralsFirstInComparisons (java-bestpractices) find String literals, that are used in comparisons and are not positioned first. Using the String literal as the receiver of e.g. equals helps to avoid NullPointerExceptions.

    This rule is replacing the two old rules PositionLiteralsFirstInComparisons and PositionLiteralsFirstInCaseInsensitiveComparisons and extends the check for the methods compareTo, compareToIgnoreCase and contentEquals in addition to equals and equalsIgnoreCase.

    Note: This rule also replaces the two mentioned rules in Java’s quickstart ruleset.

Deprecated Rules

Fixed Issues

  • apex-bestpractices
    • #2468: [apex] Unused Local Variable fails on blocks
  • core
    • #2444: [core] Support reproducible builds
    • #2484: [core] Update maven-enforcer-plugin to require Java 118
  • c#
    • #2495: [c#] Support for interpolated verbatim strings
  • java
    • #2472: [java] JavaCharStream throws an Error on invalid escape
  • java-bestpractices
    • #2145: [java] Deprecate rules PositionLiteralsFirstIn(CaseInsensitive)Comparisons in favor of LiteralsFirstInComparisons
    • #2288: [java] JUnitTestsShouldIncludeAssert: Add support for Hamcrest MatcherAssert.assertThat
    • #2437: [java] AvoidPrintStackTrace can’t detect the case e.getCause().printStackTrace()
  • java-codestyle
    • #2476: [java] MethodNamingConventions - Add support for JUnit 5 method naming
  • java-errorprone
    • #2477: [java] JUnitSpelling false-positive for JUnit5/4 tests
  • swift
    • #2473: [swift] Swift 5 (up to 5.2) support for CPD

API Changes

Deprecated APIs

Experimental APIs

Note: Experimental APIs are identified with the annotation Experimental, see its javadoc for details

External Contributions

Stats

  • 114 commits
  • 29 closed tickets & PRs
  • Days since last release: 30

24-April-2020 - 6.23.0

The PMD team is pleased to announce PMD 6.23.0.

This is a minor release.

Table Of Contents

New and noteworthy

PMD adopts Contributor Code of Conduct

To facilitate healthy and constructive community behavior PMD adopts Contributor Convenant as its code of conduct.

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

You can find the code of conduct in the file code_of_conduct.md in our repository.

Performance improvements for XPath 2.0 rules

XPath rules written with XPath 2.0 now support conversion to a rulechain rule, which improves their performance. The rulechain is a mechanism that allows several rules to be executed in a single tree traversal. Conversion to the rulechain is possible if your XPath expression looks like //someNode/... | //someOtherNode/... | ..., that is, a union of one or more path expressions that start with //. Instead of traversing the whole tree once per path expression (and per rule), a single traversal executes all rules in your ruleset as needed.

This conversion is performed automatically and cannot be disabled. The conversion should not change the result of your rules, if it does, please report a bug at https://github.com/pmd/pmd/issues

Note that XPath 1.0 support, the default XPath version, is deprecated since PMD 6.22.0. We highly recommend that you upgrade your rules to XPath 2.0. Please refer to the migration guide.

Javascript improvements for ES6

PMD uses the Rhino library to parse Javascript. The default version has been set to ES6, so that some ECMAScript 2015 features are supported. E.g. let statements and for-of loops are now parsed. However Rhino does not support all features.

New JSON renderer

PMD now supports a JSON renderer (use it with -f json on the CLI). See the documentation and example

New Rules

Fixed Issues

  • apex-design
    • #2358: [apex] Invalid Apex in Cognitive Complexity tests
  • apex-security
    • #2210: [apex] ApexCRUDViolation: Support WITH SECURITY_ENFORCED
    • #2399: [apex] ApexCRUDViolation: false positive with security enforced with line break
  • core
    • #1286: [core] Export Supporting JSON Format
    • #2019: [core] Insufficient deprecation warnings for XPath attributes
    • #2357: Add code of conduct: Contributor Covenant
    • #2426: [core] CodeClimate renderer links are dead
    • #2432: [core] Close ZIP data sources even if a runtime exception or error is thrown
  • doc
    • #2355: [doc] Improve documentation about incremental analysis
    • #2356: [doc] Add missing doc about pmd.github.io
    • #2412: [core] HTMLRenderer doesn’t render links to source files
    • #2413: [doc] Improve documentation about the available renderers (PMD/CPD)
  • java
    • #2378: [java] AbstractJUnitRule has bad performance on large code bases
  • java-bestpractices
    • #2398: [java] AbstractClassWithoutAbstractMethod false negative with inner abstract classes
  • java-codestyle
    • #1164: [java] ClassNamingConventions suggests to add Util for class containing only static constants
    • #1723: [java] UseDiamondOperator false-positive inside lambda
  • java-design
    • #2390: [java] AbstractClassWithoutAnyMethod: missing violation for nested classes
  • java-errorprone
    • #2402: [java] CloseResource possible false positive with Primitive Streams
  • java-multithreading
    • #2313: [java] Documentation for DoNotUseThreads is outdated
  • javascript
    • #1235: [javascript] Use of let results in an Empty Statement in the AST
    • #2379: [javascript] Support for-of loop
  • javascript-errorprone
    • #384: [javascript] Trailing commas not detected on French default locale

API Changes

Deprecated APIs

Internal API

Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. You can identify them with the @InternalApi annotation. You’ll also get a deprecation warning.

In ASTs

As part of the changes we’d like to do to AST classes for 7.0.0, we would like to hide some methods and constructors that rule writers should not have access to. The following usages are now deprecated in the Apex, Javascript, PL/SQL, Scala and Visualforce ASTs:

  • Manual instantiation of nodes. Constructors of node classes are deprecated and marked InternalApi. Nodes should only be obtained from the parser, which for rules, means that they never need to instantiate node themselves. Those constructors will be made package private with 7.0.0.
  • Subclassing of abstract node classes, or usage of their type. The base classes are internal API and will be hidden in version 7.0.0. You should not couple your code to them.
    • In the meantime you should use interfaces like VfNode or Node, or the other published interfaces in this package, to refer to nodes generically.
    • Concrete node classes will be made final with 7.0.0.
  • Setters found in any node class or interface. Rules should consider the AST immutable. We will make those setters package private with 7.0.0.
  • The implementation classes of Parser (eg VfParser) are deprecated and should not be used directly. Use LanguageVersionHandler#getParser instead.
  • The implementation classes of TokenManager (eg VfTokenManager) are deprecated and should not be used outside of our implementation. This also affects CPD-only modules.

These deprecations are added to the following language modules in this release. Please look at the package documentation to find out the full list of deprecations.

These deprecations have already been rolled out in a previous version for the following languages:

Outside of these packages, these changes also concern the following TokenManager implementations, and their corresponding Parser if it exists (in the same package):

In the Java AST the following attributes are deprecated and will issue a warning when used in XPath rules:

For removal

External Contributions

Stats

  • 237 commits
  • 64 closed tickets & PRs
  • Days since last release: 42

12-March-2020 - 6.22.0

The PMD team is pleased to announce PMD 6.22.0.

This is a minor release.

Table Of Contents

New and noteworthy

Java 14 Support

This release of PMD brings support for Java 14. PMD can parse Switch Expressions, which have been promoted to be a standard language feature of Java.

PMD also parses Text Blocks as String literals, which is still a preview language feature in Java 14.

The new Pattern Matching for instanceof can be used as well as Records.

Note: The Text Blocks, Pattern Matching for instanceof and Records are all preview language features of OpenJDK 14 and are not enabled by default. In order to analyze a project with PMD that uses these language features, you’ll need to enable it via the environment variable PMD_JAVA_OPTS and select the new language version 14-preview:

export PMD_JAVA_OPTS=--enable-preview
./run.sh pmd -language java -version 14-preview ...

Note: Support for the extended break statement introduced in Java 12 as a preview language feature has been removed from PMD with this version. The version “12-preview” is no longer available.

Updated PMD Designer

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

Apex Suppressions

In addition to suppressing violation with the @SuppressWarnings annotation, Apex now also supports the suppressions with a NOPMD comment. See Suppressing warnings.

Improved CPD support for C#

The C# tokenizer is now based on an antlr grammar instead of a manual written tokenizer. This should give more accurate results and especially fixes the problems with the using statement syntax (see #2139).

XPath Rules

See the new documentation about Writing XPath Rules.

Note: As of PMD version 6.22.0, XPath versions 1.0 and the 1.0 compatibility mode are deprecated. XPath 2.0 is superior in many ways, for example for its support for type checking, sequence values, or quantified expressions. For a detailed but approachable review of the features of XPath 2.0 and above, see the Saxon documentation.

New Rules

  • The Rule CognitiveComplexity (apex-design) finds methods and classes that are highly complex and therefore difficult to read and more costly to maintain. In contrast to cyclomatic complexity, this rule uses “Cognitive Complexity”, which is a measure of how difficult it is for humans to read and understand a method.

  • The Rule TestMethodsMustBeInTestClasses (apex-errorprone) finds test methods that are not residing in a test class. The test methods should be moved to a proper test class. Support for tests inside functional classes was removed in Spring-13 (API Version 27.0), making classes that violate this rule fail compile-time. This rule is however useful when dealing with legacy code.

Fixed Issues

  • apex
    • #1087: [apex] Support suppression via //NOPMD
    • #2306: [apex] Switch statements are not parsed/supported
  • apex-design
    • #2162: [apex] Cognitive Complexity rule
  • apex-errorprone
    • #639: [apex] Test methods should not be in classes other than test classes
  • cs
    • #2139: [cs] CPD doesn’t understand alternate using statement syntax with C# 8.0
  • doc
    • #2274: [doc] Java API documentation for PMD
  • java
    • #2159: [java] Prepare for JDK 14
    • #2268: [java] Improve TypeHelper resilience
  • java-bestpractices
    • #2277: [java] FP in UnusedImports for ambiguous static on-demand imports
  • java-design
    • #911: [java] UselessOverridingMethod false positive when elevating access modifier
  • java-errorprone
    • #2242: [java] False-positive MisplacedNullCheck reported
    • #2250: [java] InvalidLogMessageFormat flags logging calls using a slf4j-Marker
    • #2255: [java] InvalidLogMessageFormat false-positive for a lambda argument
  • java-performance
    • #2275: [java] AppendCharacterWithChar flags literals in an expression
  • plsql
    • #2325: [plsql] NullPointerException while running parsing test for CREATE TRIGGER
    • #2327: [plsql] Parsing of WHERE CURRENT OF
    • #2328: [plsql] Support XMLROOT
    • #2331: [plsql] Fix in Comment statement
    • #2332: [plsql] Fixed Execute Immediate statement parsing
    • #2340: [plsql] Fixed parsing / as divide or execute

API Changes

Deprecated APIs

Internal API

Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. You can identify them with the @InternalApi annotation. You’ll also get a deprecation warning.

For removal
In ASTs (JSP)

As part of the changes we’d like to do to AST classes for 7.0.0, we would like to hide some methods and constructors that rule writers should not have access to. The following usages are now deprecated in the JSP AST (with other languages to come):

  • Manual instantiation of nodes. Constructors of node classes are deprecated and marked InternalApi. Nodes should only be obtained from the parser, which for rules, means that they never need to instantiate node themselves. Those constructors will be made package private with 7.0.0.
  • Subclassing of abstract node classes, or usage of their type. The base classes are internal API and will be hidden in version 7.0.0. You should not couple your code to them.
    • In the meantime you should use interfaces like JspNode or Node, or the other published interfaces in this package, to refer to nodes generically.
    • Concrete node classes will be made final with 7.0.0.
  • Setters found in any node class or interface. Rules should consider the AST immutable. We will make those setters package private with 7.0.0.
  • The class JspParser is deprecated and should not be used directly. Use LanguageVersionHandler#getParser instead.

Please look at net.sourceforge.pmd.lang.jsp.ast to find out the full list of deprecations.

In ASTs (Velocity)

As part of the changes we’d like to do to AST classes for 7.0.0, we would like to hide some methods and constructors that rule writers should not have access to. The following usages are now deprecated in the VM AST (with other languages to come):

  • Manual instantiation of nodes. Constructors of node classes are deprecated and marked InternalApi. Nodes should only be obtained from the parser, which for rules, means that they never need to instantiate node themselves. Those constructors will be made package private with 7.0.0.
  • Subclassing of abstract node classes, or usage of their type. The base classes are internal API and will be hidden in version 7.0.0. You should not couple your code to them.
    • In the meantime you should use interfaces like VmNode or Node, or the other published interfaces in this package, to refer to nodes generically.
    • Concrete node classes will be made final with 7.0.0.
  • Setters found in any node class or interface. Rules should consider the AST immutable. We will make those setters package private with 7.0.0.
  • The package net.sourceforge.pmd.lang.vm.directive as well as the classes DirectiveMapper and LogUtil are deprecated for removal. They were only used internally during parsing.
  • The class VmParser is deprecated and should not be used directly. Use LanguageVersionHandler#getParser instead.

Please look at net.sourceforge.pmd.lang.vm.ast to find out the full list of deprecations.

PLSQL AST

The production and node ASTCursorBody was unnecessary, not used and has been removed. Cursors have been already parsed as ASTCursorSpecification.

External Contributions

24-January-2020 - 6.21.0

The PMD team is pleased to announce PMD 6.21.0.

This is a minor release.

Table Of Contents

New and noteworthy

Modelica support

Thanks to Anatoly Trosinenko PMD supports now a new language: Modelica is a language to model complex physical systems. Both PMD and CPD are supported and there are already 3 rules available. The PMD Designer supports syntax highlighting for Modelica.

While the language implementation is quite complete, Modelica support is considered experimental for now. This is to allow us to change the rule API (e.g. the AST classes) slightly and improve the implementation based on your feedback.

Simple XML dump of AST

We added a experimental feature to dump the AST of a source file into XML. The XML format is of course PMD specific and language dependent. That XML file can be used to execute (XPath) queries against without PMD. It can also be used as a textual visualization of the AST if you don’t want to use the Designer.

This feature is experimental and might change or even be removed in the future, if it is not useful. A short description how to use it is available under Creating XML dump of the AST.

Any feedback about it, especially about your use cases, is highly appreciated.

Updated Apex Support

  • The Apex language support has been bumped to version 48 (Spring ‘20). All new language features are now properly parsed and processed.

CPD XML format

The CPD XML output format has been enhanced to also report column information for found duplications in addition to the line information. This allows to display the exact tokens, that are considered duplicate.

If a CPD language doesn’t provide these exact information, then these additional attributes are omitted.

Each <file> element in the XML format now has 3 new attributes:

  • attribute endline
  • attribute column (if there is column information available)
  • attribute endcolumn (if there is column information available)

Modified Rules

  • The Java rule AvoidLiteralsInIfCondition (java-errorprone) has a new property ignoreExpressions. This property is set by default to true in order to maintain compatibility. If this property is set to false, then literals in more complex expressions are considered as well.

  • The Apex rule ApexCSRF (apex-errorprone) has been moved from category “Security” to “Error Prone”. The Apex runtime already prevents DML statements from being executed, but only at runtime. So, if you try to do this, you’ll get an error at runtime, hence this is error prone. See also the discussion on #2064.

  • The Java rule CommentRequired (java-documentation) has a new property classCommentRequirement. This replaces the now deprecated property headerCommentRequirement, since the name was misleading. (File) header comments are not checked, but class comments are.

Fixed Issues

  • apex
    • #2208: [apex] ASTFormalComment should implement ApexNode<T>
  • core
    • #1984: [java] Cyclomatic complexity is misreported (lack of clearing metrics cache)
    • #2006: [core] PMD should warn about multiple instances of the same rule in a ruleset
    • #2161: [core] ResourceLoader is deprecated and marked as internal but is exposed
    • #2170: [core] DocumentFile doesn’t preserve newlines
  • doc
    • #2214: [doc] Link broken in pmd documentation for writing Xpath rules
  • java
    • #2212: [java] JavaRuleViolation reports wrong class name
  • java-bestpractices
    • #2149: [java] JUnitAssertionsShouldIncludeMessage - False positive with assertEquals and JUnit5
  • java-codestyle
    • #2167: [java] UnnecessaryLocalBeforeReturn false positive with variable captured by method reference
  • java-documentation
    • #1683: [java] CommentRequired property names are inconsistent
  • java-errorprone
    • #2140: [java] AvoidLiteralsInIfCondition: false negative for expressions
    • #2196: [java] InvalidLogMessageFormat does not detect extra parameters when no placeholders
  • java-performance
    • #2141: [java] StringInstatiation: False negative with String-array access
  • plsql
    • #2008: [plsql] In StringLiteral using alternative quoting mechanism single quotes cause parsing errors
    • #2009: [plsql] Multiple DDL commands are skipped during parsing

API Changes

Deprecated APIs

Internal API

Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. You can identify them with the @InternalApi annotation. You’ll also get a deprecation warning.

For removal

External Contributions

29-November-2019 - 6.20.0

The PMD team is pleased to announce PMD 6.20.0.

This is a minor release.

Table Of Contents

Fixed Issues

  • apex
    • #2092: [apex] ApexLexer logs visible when Apex is the selected language upon starting the designer
    • #2136: [apex] Provide access to underlying query of SoqlExpression
  • core
    • #2002: [doc] Issue with http://pmdapplied.com/ linking to a gambling Web site
    • #2062: [core] Shortnames parameter does not work with Ant
    • #2090: [ci] Release notes and draft releases
    • #2096: [core] Referencing category errorprone.xml produces deprecation warnings for InvalidSlf4jMessageFormat
  • java
    • #1861: [java] Be more lenient with version numbers
    • #2105: [java] Wrong name for inner classes in violations
  • java-bestpractices
    • #2016: [java] UnusedImports: False positive if wildcard is used and only static methods
  • java-codestyle
    • #1362: [java] LinguisticNaming flags Predicates with boolean-style names
    • #2029: [java] UnnecessaryFullyQualifiedName false-positive for non-static nested classes
    • #2098: [java] UnnecessaryFullyQualifiedName: regression / false positive
  • java-design
    • #2075: [java] ImmutableField false positive with inner class
    • #2125: [java] ImmutableField: False positive when variable is updated in conditional loop
  • java-errorprone
    • #2102: [java] False positive MissingStaticMethodInNonInstantiatableClass when inheritors are instantiable

External Contributions

31-October-2019 - 6.19.0

The PMD team is pleased to announce PMD 6.19.0.

This is a minor release.

Table Of Contents

New and noteworthy

Updated PMD Designer

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

Java Metrics

Modified Rules

  • The Java rules InvalidLogMessageFormat and MoreThanOneLogger (java-errorprone) now both support Log4j2. Note that the rule “InvalidSlf4jMessageFormat” has been renamed to “InvalidLogMessageFormat” to reflect the fact, that it now supports more than slf4j.

  • The Java rule LawOfDemeter (java-design) ignores now also Builders, that are not assigned to a local variable, but just directly used within a method call chain. The method, that creates the builder needs to end with “Builder”, e.g. newBuilder() or initBuilder() works. This change fixes a couple of false positives.

  • The Java rule DataflowAnomalyAnalysis (java-errorprone) doesn’t check for UR anomalies (undefined and then referenced) anymore. These checks were all false-positives, since actual UR occurrences would lead to compile errors.

  • The java rule DoNotUseThreads (java-multithreading) has been changed to not report usages of java.lang.Runnable anymore. Just using Runnable does not automatically create a new thread. While the check for Runnable has been removed, the rule now additionally checks for usages of Executors and ExecutorService. Both create new threads, which are not managed by a J2EE server.

Renamed Rules

Fixed Issues

  • core
    • #1978: [core] PMD fails on excluding unknown rules
    • #2014: [core] Making add(SourceCode sourceCode) public for alternative file systems
    • #2020: [core] Wrong deprecation warnings for unused XPath attributes
    • #2036: [core] Wrong include/exclude patterns are silently ignored
    • #2048: [core] Enable type resolution by default for XPath rules
    • #2067: [core] Build issue on Windows
    • #2068: [core] Rule loader should use the same resources loader for the ruleset
    • #2071: [ci] Add travis build on windows
    • #2072: [test][core] Not enough info in “test setup error” when numbers of lines do not match
    • #2082: [core] Incorrect logging of deprecated/renamed rules
  • java
    • #2042: [java] PMD crashes with ClassFormatError: Absent Code attribute…
  • java-bestpractices
    • #1531: [java] UnusedPrivateMethod false-positive with method result
    • #2025: [java] UnusedImports when @see / @link pattern includes a FQCN
  • java-codestyle
    • #2017: [java] UnnecessaryFullyQualifiedName triggered for inner class
  • java-design
    • #1912: [java] Metrics not computed correctly with annotations
  • java-errorprone
    • #336: [java] InvalidSlf4jMessageFormat applies to log4j2
    • #1636: [java] Stop checking UR anomalies for DataflowAnomalyAnalysis
  • java-multithreading
    • #1627: [java] DoNotUseThreads should not warn on Runnable
  • doc
    • #2058: [doc] CLI reference for -norulesetcompatibility shows a boolean default value

API Changes

Deprecated APIs

For removal
Internal APIs

External Contributions

15-September-2019 - 6.18.0

The PMD team is pleased to announce PMD 6.18.0.

This is a minor release.

Table Of Contents

New and noteworthy

Java 13 Support

This release of PMD brings support for Java 13. PMD can parse Switch Expressions with the new yield statement and resolve the type of such an expression.

PMD also parses Text Blocks as String literals.

Note: The Switch Expressions and Text Blocks are a preview language feature of OpenJDK 13 and are not enabled by default. In order to analyze a project with PMD that uses these language features, you’ll need to enable it via the environment variable PMD_JAVA_OPTS and select the new language version 13-preview:

export PMD_JAVA_OPTS=--enable-preview
./run.sh pmd -language java -version 13-preview ...

Note: Support for the extended break statement introduced in Java 12 as a preview language feature will be removed with the next PMD version 6.19.0.

Full support for Scala

Thanks to Chris Smith PMD now fully supports Scala. Now rules for analyzing Scala code can be developed in addition to the Copy-Paste-Detection (CPD) functionality. There are no rules yet, so contributions are welcome.

Additionally Scala support has been upgraded from 2.12.4 to 2.13.

New rule designer documentation

The documentation for the rule designer is now available on the main PMD documentation page: Rule Designer Reference. Check it out to learn about the usage and features of the rule designer.

New rules

  • The Java rule AvoidMessageDigestField (java-bestpractices) detects fields of the type java.security.MessageDigest. Using a message digest instance as a field would need to be synchronized, as it can easily be used by multiple threads. Without synchronization the calculated hash could be entirely wrong. Instead of declaring this as a field and synchronize access to use it from multiple threads, a new instance should be created when needed. This rule is also active when using java’s quickstart ruleset.

  • The Apex rule DebugsShouldUseLoggingLevel (apex-bestpractices) detects usages of System.debug() method calls that are used without specifying the log level. Having the log level specified provides a cleaner log, and improves readability of it.

Modified Rules

  • The Java rule CloseResource (java-errorprone) now ignores by default instances of java.util.stream.Stream. These streams are AutoCloseable, but most streams are backed by collections, arrays, or generating functions, which require no special resource management. However, there are some exceptions: The stream returned by Files::lines(Path) is backed by a actual file and needs to be closed. These instances won’t be found by default by the rule anymore.

Fixed Issues

  • all
    • #1465: [core] Stylesheet pmd-report.xslt fails to display filepath if ‘java’ in path
    • #1923: [core] Incremental analysis does not work with shortnames
    • #1983: [core] Avoid crashes with analysis cache when classpath references non-existing directories
    • #1990: [core] Incremental analysis mixes XPath rule violations
  • apex
    • #1901: [apex] Expose super type name of UserClass
    • #1942: [apex] Add best practice rule for debug statements in Apex
  • java
    • #1930: [java] Add Java 13 support
  • java-bestpractices
    • #1227: [java] UnusedFormalParameter should explain checkAll better
    • #1862: [java] New rule for MessageDigest.getInstance
    • #1952: [java] UnusedPrivateField not triggering if @Value annotation present
  • java-codestyle
    • #1951: [java] UnnecessaryFullyQualifiedName rule triggered when variable name clashes with package name
  • java-errorprone
    • #1922: [java] CloseResource possible false positive with Streams
    • #1966: [java] CloseResource false positive if Stream is passed as method parameter
    • #1967: [java] CloseResource false positive with late assignment of variable
  • plsql
    • #1933: [plsql] ParseException with cursor declared in anonymous block
    • #1935: [plsql] ParseException with SELECT INTO record defined as global variable
    • #1936: [plslq] ParseException with cursor inside procedure declaration
    • #1946: [plsql] ParseException with using TRIM inside IF statements condition
    • #1947: [plsql] ParseError - SELECT with FOR UPDATE OF
    • #1948: [plsql] ParseException with INSERT INTO using package global variables
    • #1950: [plsql] ParseException with UPDATE and package record variable
    • #1953: [plsql] ParseException with WITH in CURSOR

API Changes

Changes to Renderer

  • Each renderer has now a new method Renderer#setUseShortNames which is used for implementing the “shortnames” CLI option. The method is automatically called by PMD, if this CLI option is in use. When rendering filenames to the report, the new helper method AbstractRenderer#determineFileName should be used. This will change the filename to a short name, if the CLI option “shortnames” is used.

    Not adjusting custom renderers will make them render always the full file names and not honoring the CLI option “shortnames”.

Deprecated APIs

For removal
Internal APIs

Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. You can identify them with the @InternalApi annotation. You’ll also get a deprecation warning.

External Contributions

28-July-2019 - 6.17.0

The PMD team is pleased to announce PMD 6.17.0.

This is a minor release.

Table Of Contents

New and noteworthy

Updated PMD Designer

This PMD release ships a new version of the pmd-designer. For the changes, see PMD Designer Changelog. It contains a new feature to edit test cases directly within the designer. Any feedback is highly appreciated.

Lua support

Thanks to the contribution from Maikel Steneker, and built on top of the ongoing efforts to fully support Antlr-based languages, PMD now has CPD support for Lua.

Being based on a proper Antlr grammar, CPD can:

Modified Rules

  • The Java rule CloseResource (java-errorprone) ignores now by default java.io.ByteArrayInputStream and java.io.CharArrayWriter. Such streams/writers do not need to be closed.

  • The Java rule MissingStaticMethodInNonInstantiatableClass (java-errorprone) has now the new property annotations. When one of the private constructors is annotated with one of the annotations, then the class is not considered non-instantiatable anymore and no violation will be reported. By default, Spring’s @Autowired and Java EE’s @Inject annotations are recognized.

Fixed Issues

  • core
    • #1913: [core] “-help” CLI option ends with status code != 0
  • doc
    • #1896: [doc] Error in changelog 6.16.0 due to not properly closed rule tag
    • #1898: [doc] Incorrect code example for DoubleBraceInitialization in documentation on website
    • #1906: [doc] Broken link for adding own CPD languages
    • #1909: [doc] Sample usage example refers to deprecated ruleset “basic.xml” instead of “quickstart.xml”
  • java
    • #1910: [java] ATFD calculation problem
  • java-errorprone
    • #1749: [java] DD False Positive in DataflowAnomalyAnalysis
    • #1832: [java] False positives for MissingStaticMethodInNonInstantiatableClass when DI is used
    • #1921: [java] CloseResource false positive with ByteArrayInputStream
  • java-multithreading
    • #1903: [java] UnsynchronizedStaticFormatter doesn’t allow block-level synchronization when using allowMethodLevelSynchronization=true
  • plsql
    • #1902: [pslql] ParseException when parsing (+)
  • xml
    • #1666: [xml] wrong cdata rule description and examples

External Contributions

  • #1869: [xml] fix #1666 wrong cdata rule description and examples - Artem
  • #1892: [lua] [cpd] Added CPD support for Lua - Maikel Steneker
  • #1905: [java] DataflowAnomalyAnalysis Rule in right order - YoonhoChoi96
  • #1908: [doc] Update ruleset filename from deprecated basic.xml to quickstart.xml - crunsk
  • #1916: [java] Exclude Autowired and Inject for MissingStaticMethodInNonInstantiatableClass - AnthonyKot
  • #1917: [core] Add ‘no error’ return option, and assign it to the cli when the help command is invoked - Renato Oliveira

30-June-2019 - 6.16.0

The PMD team is pleased to announce PMD 6.16.0.

This is a minor release.

Table Of Contents

New and noteworthy

Updated PMD Designer

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

PLSQL Grammar Updates

The grammar has been updated to support inline constraints in CREATE TABLE statements. Additionally, the CREATE TABLE statement may now be followed by physical properties and table properties. However, these properties are skipped over during parsing.

The CREATE VIEW statement now supports subquery views.

The EXTRACT function can now be parsed correctly. It is used to extract values from a specified datetime field. Also date time literals are parsed now correctly.

The CASE expression can now be properly used within SELECT statements.

Table aliases are now supported when specifying columns in INSERT INTO clauses.

New Rules

  • The Java rule DoubleBraceInitialization (java-bestpractices) detects non static initializers in anonymous classes also known as “double brace initialization”. This can be problematic, since a new class file is generated and object holds a strong reference to the surrounding class.

    Note: This rule is also part of the Java quickstart ruleset (rulesets/java/quickstart.xml).

Modified Rules

  • The Java rule UnusedPrivateField (java-bestpractices) now ignores by default fields, that are annotated with the Lombok experimental annotation @Delegate. This can be customized with the property ignoredAnnotations.

  • The Java rule SingularField (java-design) now ignores by default fields, that are annotated with the Lombok experimental annotation @Delegate. This can be customized with the property ignoredAnnotations.

  • The Java rules UnsynchronizedStaticFormatter and UnsynchronizedStaticDateFormatter (java-multithreading) now prefer synchronized blocks by default. They will raise a violation, if the synchronization is implemented on the method level. To allow the old behavior, the new property allowMethodLevelSynchronization can be enabled.

  • The Java rule UseUtilityClass (java-design) has a new property ignoredAnnotations. By default, classes that are annotated with Lombok’s @UtilityClass are ignored now.

  • The Java rule NonStaticInitializer (java-errorprone) does not report non static initializers in anonymous classes anymore. For this use case, there is a new rule now: DoubleBraceInitialization (java-bestpractices).

  • The Java rule CommentDefaultAccessModifier (java-codestyle) was enhanced in the last version 6.15.0 to check also top-level types by default. This created many new violations. Missing the access modifier for top-level types is not so critical, since it only decreases the visibility of the type.

    The default behaviour has been restored. If you want to enable the check for top-level types, you can use the new property checkTopLevelTypes.

  • The Java rule CloseResource (java-errorprone) now by default searches for any unclosed java.lang.AutoCloseable resource. This includes now the standard java.io.*Stream classes. Previously only SQL-related resources were considered by this rule. The types can still be configured via the types property. Some resources do not need to be closed (e.g. ByteArrayOutputStream). These exceptions can be configured via the new property allowedResourceTypes. In order to restore the old behaviour, just remove the type java.lang.AutoCloseable from the types property and keep the remaining SQL-related classes.

Deprecated Rules

  • The Java rule AvoidFinalLocalVariable (java-codestyle) has been deprecated and will be removed with PMD 7.0.0. The rule is controversial and also contradicts other existing rules such as LocalVariableCouldBeFinal. If the goal is to avoid defining constants in a scope smaller than the class, then the rule AvoidDuplicateLiterals should be used instead.

Fixed Issues

  • apex
    • #1664: [apex] False positive ApexSharingViolationsRule, unsupported Apex feature
  • java
    • #1848: [java] Local classes should preserve their modifiers
  • java-bestpractices
    • #1703: [java] UnusedPrivateField on member annotated with lombok @Delegate
    • #1845: [java] Regression in MethodReturnsInternalArray not handling enums
    • #1854: [java] Rule to check for double brace initialisation
  • java-codestyle
    • #1612: [java] Deprecate AvoidFinalLocalVariable
    • #1880: [java] CommentDefaultAccessModifier should be configurable for top-level classes
  • java-design
    • #1094: [java] UseUtilityClass should be LombokAware
  • java-errorprone
    • #1000: [java] The rule CloseResource should deal with IO stream as default
    • #1853: [java] False positive for NonStaticInitializer in anonymous class
  • java-multithreading
    • #1814: [java] UnsynchronizedStaticFormatter documentation and implementation wrong
    • #1815: [java] False negative in UnsynchronizedStaticFormatter
  • plsql
    • #1828: [plsql] Parentheses stopped working
    • #1850: [plsql] Parsing errors with INSERT using returning or records and TRIM expression
    • #1873: [plsql] Expression list not working
    • #1878: [pslql] ParseException when parsing USING
    • #1879: [pslql] ParseException when parsing LEFT JOIN

API Changes

Deprecated APIs

Reminder: Please don’t use members marked with the annotation InternalApi, as they will likely be removed, hidden, or otherwise intentionally broken with 7.0.0.

In ASTs

As part of the changes we’d like to do to AST classes for 7.0.0, we would like to hide some methods and constructors that rule writers should not have access to. The following usages are now deprecated in the Java AST (with other languages to come):

  • Manual instantiation of nodes. Constructors of node classes are deprecated and marked InternalApi. Nodes should only be obtained from the parser, which for rules, means that never need to instantiate node themselves. Those constructors will be made package private with 7.0.0.
  • Subclassing of abstract node classes, or usage of their type. Version 7.0.0 will bring a new set of abstractions that will be public API, but the base classes are and will stay internal. You should not couple your code to them.
    • In the meantime you should use interfaces like JavaNode or Node, or the other published interfaces in this package, to refer to nodes generically.
    • Concrete node classes will be made final with 7.0.0.
  • Setters found in any node class or interface. Rules should consider the AST immutable. We will make those setters package private with 7.0.0.

Please look at net.sourceforge.pmd.lang.java.ast to find out the full list of deprecations.

External Contributions

26-May-2019 - 6.15.0

The PMD team is pleased to announce PMD 6.15.0.

This is a minor release.

Table Of Contents

New and noteworthy

Enhanced Matlab support

Thanks to the contributions from Maikel Steneker CPD for Matlab can now parse Matlab programs which use the question mark operator to specify access to class members:

classdef Class1
properties (SetAccess = ?Class2)

CPD also understands now double quoted strings, which are supported since version R2017a of Matlab:

str = "This is a string"

Enhanced C++ support

CPD now supports digit separators in C++ (language module “cpp”). This is a C++14 feature.

Example: auto integer_literal = 1'000'000;

The single quotes can be used to add some structure to large numbers.

CPD also parses raw string literals now correctly (see #1784).

New Rules

  • The new Apex rule FieldNamingConventions (apex-codestyle) checks the naming conventions for field declarations. By default this rule uses the standard Apex naming convention (Camel case), but it can be configured through properties.

  • The new Apex rule FormalParameterNamingConventions (apex-codestyle) checks the naming conventions for formal parameters of methods. By default this rule uses the standard Apex naming convention (Camel case), but it can be configured through properties.

  • The new Apex rule LocalVariableNamingConventions (apex-codestyle) checks the naming conventions for local variable declarations. By default this rule uses the standard Apex naming convention (Camel case), but it can be configured through properties.

  • The new Apex rule PropertyNamingConventions (apex-codestyle) checks the naming conventions for property declarations. By default this rule uses the standard Apex naming convention (Camel case), but it can be configured through properties.

  • The new Java rule UseShortArrayInitializer (java-codestyle) searches for array initialization expressions, which can be written shorter.

Modified Rules

  • The Apex rule ClassNamingConventions (apex-codestyle) can now be configured using various properties for the specific kind of type declarations (e.g. class, interface, enum). As before, this rule uses by default the standard Apex naming convention (Pascal case).

  • The Apex rule MethodNamingConventions (apex-codestyle) can now be configured using various properties to differenciate e.g. static methods and test methods. As before, this rule uses by default the standard Apex naming convention (Camel case).

  • The Java rule FieldNamingConventions (java-codestyle) now by default ignores the field serialPersistentFields. Since this is a field which needs to have this special name, no field naming conventions can be applied here. It is excluded the same way like serialVersionUID via the property exclusions.

  • The Java rule CommentRequired (java-documentation) has a new property serialPersistentFieldsCommentRequired with the default value “Ignored”. This means that from now on comments for the field serialPersistentFields are not required anymore. You can change the property to restore the old behavior.

  • The Java rule ProperLogger (java-errorprone) has two new properties to configure the logger class (e.g. “org.slf4j.Logger”) and the logger name of the special case, when the logger is not static. The name of the static logger variable was already configurable. The new property “loggerClass” allows to use this rule for different logging frameworks. This rule covers all the cases of the now deprecated rule LoggerIsNotStaticFinal.

  • The Java rule CommentDefaultAccessModifier (java-codestyle) now reports also missing comments for top-level classes and annotations, that are package-private.

Deprecated Rules

Fixed Issues

  • apex
    • #1321: [apex] Should VariableNamingConventions require properties to start with a lowercase letter?
    • #1783: [apex] comments on constructor not recognized when the Class has inner class
  • cpp
    • #1784: [cpp] Improve support for raw string literals
  • dart
    • #1809: [dart] [cpd] Parse error with escape sequences
  • java
    • #1842: [java] Annotated module declarations cause parse error
  • java-bestpractices
    • #1738: [java] MethodReturnsInternalArray does not work in inner classes
  • java-codestyle
    • #1495: [java] Rule to detect overly verbose array initializiation
    • #1684: [java] Properly whitelist serialPersistentFields
    • #1804: [java] NPE in UnnecessaryLocalBeforeReturnRule
  • python
    • #1810: [python] [cpd] Parse error when using Python 2 backticks
  • matlab
    • #1830: [matlab] [cpd] Parse error with comments
    • #1793: [java] CommentDefaultAccessModifier not working for classes

API Changes

Deprecated APIs

For removal

External Contributions

28-April-2019 - 6.14.0

The PMD team is pleased to announce PMD 6.14.0.

This is a minor release.

Table Of Contents

New and noteworthy

Dart support

Thanks to the contribution from Maikel Steneker, and built on top of the ongoing efforts to fully support Antlr-based languages, PMD now has CPD support for Dart.

Being based on a proper Antlr grammar, CPD can:

Updated PMD Designer

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

Modified Rules

  • The Java rule AssignmentToNonFinalStatic (java-errorprone) will now report on each assignment made within a constructor rather than on the field declaration. This makes it easier for developers to find the offending statements.

  • The Java rule NoPackage (java-codestyle) will now report additionally enums and annotations that do not have a package declaration.

Fixed Issues

  • all
    • #1515: [core] Module pmd-lang-test is missing javadoc artifact
    • #1788: [cpd] [core] Use better ClassLoader for ServiceLoader in LanguageFactory
    • #1794: [core] Ruleset Compatibility fails with excluding rules
  • go
    • #1751: [go] Parsing errors encountered with escaped backslash
  • java
    • #1532: [java] NPE with incomplete auxclasspath
    • #1691: [java] Possible Data Race in JavaTypeDefinitionSimple.getGenericType
    • #1729: [java] JavaRuleViolation loses information in className field when class has package-private access level
  • java-bestpractices
    • #1190: [java] UnusedLocalVariable/UnusedPrivateField false-positive
    • #1720: [java] UnusedImports false positive for Javadoc link with array type
  • java-codestyle
    • #1755: [java] False negative in UnnecessaryLocalBeforeReturn when splitting statements across multiple lines
    • #1782: [java] NoPackage: False Negative for enums
  • java-design
    • #1760: [java] UseObjectForClearerAPI flags private methods

API Changes

No changes.

External Contributions

31-March-2019 - 6.13.0

The PMD team is pleased to announce PMD 6.13.0.

This is a minor release.

Table Of Contents

New and noteworthy

We are still searching for a new logo for PMD for the next major release.

Learn more about how to participate on github issue 1663.

Java 12 Support

This release of PMD brings support for Java 12. PMD can parse the new Switch Expressions and resolve the type of such an expression.

Note: The Switch Expressions are a preview language feature of OpenJDK 12 and are not enabled by default. In order to analyze a project with PMD that uses these language features, you’ll need to enable it via the new environment variable PMD_JAVA_OPTS:

export PMD_JAVA_OPTS=--enable-preview
./run.sh pmd ...

Quickstart Ruleset for Apex

PMD provides now a quickstart ruleset for Salesforce.com Apex, which you can use as a base ruleset to get your custom ruleset started. You can reference it with rulesets/apex/quickstart.xml. You are strongly encouraged to create your own ruleset though.

The quickstart ruleset has the intention, to be useful out-of-the-box for many projects. Therefore it references only rules, that are most likely to apply everywhere.

Any feedback would be greatly appreciated.

PMD Designer

The rule designer’s codebase has been moved out of the main repository and will be developed at pmd/pmd-designer from now on. The maven coordinates will stay the same for the time being. The designer will still be shipped with PMD’s binaries.

Improved Apex Support

  • Many AST nodes now expose more information which makes it easier to write XPath-based rules for Apex. Here are some examples:
    • Annotation[@Resolved = false()] finds unsupported annotations.
    • AnnotationParameter[@Name='RestResource'][@Value='/myurl'] gives access to annotation parameters.
    • CatchBlockStatement[@ExceptionType='Exception'][@VariableName='e'] finds catch block for specific exception types.
    • Field[@Type='String'] find all String fields, Field[string-length(@Name) < 5] finds all fields with short names and Field[@Value='a'] find alls fields, that are initialized with a specific value.
    • LiteralExpression[@String = true()] finds all String literals. There are attributes for each type: @Boolean, @Integer, @Double, @Long, @Decimal, @Null.
    • Method[@Constructor = true()] selects all constructors. Method[@ReturnType = 'String'] selects all methods that return a String.
    • The ModifierNode node has a couple of attributes to check for the existence of specific modifiers: @Test, @TestOrTestSetup, @WithSharing, @WithoutSharing, @InheritedSharing, @WebService, @Global, @Override.
    • Many nodes now expose their type. E.g. with Parameter[@Type='Integer'] you can find all method parameters of type Integer. The same attribute Type exists as well for: NewObjectExpression, Property, VariableDeclaration.
    • VariableExpression[@Image='i'] finds all variable usages of the variable “i”.

New Rules

  • The new Java rule AvoidUncheckedExceptionsInSignatures (java-design) finds methods or constructors that declare unchecked exceptions in their throws clause. This forces the caller to handle the exception, even though it is a runtime exception.

  • The new Java rule DetachedTestCase (java-errorprone) searches for public methods in test classes, which are not annotated with @Test. These methods might be test cases where the annotation has been forgotten. Because of that those test cases are never executed.

  • The new Java rule WhileLoopWithLiteralBoolean (java-bestpractices) finds Do-While-Loops and While-Loops that can be simplified since they use simply true or false as their loop condition.

  • The new Apex rule ApexAssertionsShouldIncludeMessage (apex-bestpractices) searches for assertions in unit tests and checks, whether they use a message argument.

  • The new Apex rule ApexUnitTestMethodShouldHaveIsTestAnnotation (apex-bestpractices) searches for methods in test classes, which are missing the @IsTest annotation.

  • The new PLSQL rule AvoidTabCharacter (plsql-codestyle) checks, that there are no tab characters (“\t”) in the source file.

  • The new PLSQL rule LineLength (plsql-codestyle) helps to enforce a maximum line length.

Fixed Issues

  • doc
    • #1721: [doc] Documentation provides an invalid property configuration example
  • java
    • #1537: [java] Java 12 support
  • java-bestpractices
    • #1701: [java] UseTryWithResources does not handle multiple argument close methods
  • java-codestyle
    • #1527: [java] UseUnderscoresInNumericLiterals false positive on floating point numbers
    • #1674: [java] documentation of CommentDefaultAccessModifier is wrong
  • java-errorprone
    • #1570: [java] AvoidDuplicateLiterals warning about deprecated separator property when not used
  • plsql
    • #1510: [plsql] Support XMLTABLE functions
    • #1716: [plsql] Support access to whole plsql code
    • #1731: [pslql] ParseException when parsing ELSIF
    • #1733: [plsql] % not supported in “TestSearch%notfound”
    • #1734: [plsql] TooManyMethods false-negative
    • #1735: [plsql] False-negatives for TO_DATE_TO_CHAR, TO_DATEWithoutDateFormat, TO_TIMESTAMPWithoutDateFormat

API Changes

Command Line Interface

The start scripts run.sh, pmd.bat and cpd.bat support the new environment variable PMD_JAVA_OPTS. This can be used to set arbitrary JVM options for running PMD, such as memory settings (e.g. PMD_JAVA_OPTS=-Xmx512m) or enable preview language features (e.g. PMD_JAVA_OPTS=--enable-preview).

The previously available variables such as OPTS or HEAPSIZE are deprecated and will be removed with PMD 7.0.0.

Deprecated API

  • CodeClimateRule is deprecated in 7.0.0 because it was unused for 2 years and created an unwanted dependency. Properties “cc_categories”, “cc_remediation_points_multiplier”, “cc_block_highlighting” will also be removed. See #1702 for more.

  • The Apex ruleset rulesets/apex/ruleset.xml has been deprecated and will be removed in 7.0.0. Please use the new quickstart ruleset rulesets/apex/quickstart.xml instead.

External Contributions

24-February-2019 - 6.12.0

The PMD team is pleased to announce PMD 6.12.0.

This is a minor release.

Table Of Contents

New and noteworthy

Call For Logo

PMD’s logo was great for a long time. But now we want to take the opportunity with the next major release to change our logo in order to use a more “politically correct” one.

Learn more about how to participate on github issue 1663.

CPD Suppression for Antlr-based languages

ITBA students Matías Fraga, Tomi De Lucca and Lucas Soncini keep working on bringing full Antlr support to PMD. For this release, they have implemented token filtering in an equivalent way as we did for JavaCC languages, adding support for CPD suppressions through CPD-OFF and CPD-ON comments for all Antlr-based languages.

This means, you can now ignore arbitrary blocks of code on:

  • Go
  • Kotlin
  • Swift

Simply start the suppression with any comment (single or multiline) containing CPD-OFF, and resume again with a comment containing CPD-ON.

More information is available in the user documentation.

PL/SQL Grammar improvements

  • In this release, many more parser bugs in our PL/SQL support have been fixed. This adds more complete support for UPDATE statements and subqueries and hierarchical queries in SELECT statements.
  • Support for analytic functions such as LISTAGG has been added.
  • Conditions in WHERE clauses support now REGEX_LIKE and multiset conditions.

New Rules

  • The new Java rule UseTryWithResources (java-bestpractices) searches for try-blocks, that could be changed to a try-with-resources statement. This statement ensures that each resource is closed at the end of the statement and is available since Java 7.

Modified Rules

  • The Apex rule MethodNamingConventions (apex-codestyle) has a new property skipTestMethodUnderscores, which is by default disabled. The new property allows for ignoring all test methods, either using the testMethod modifier or simply annotating them @isTest.

Fixed Issues

  • all
    • #1462: [core] Failed build on Windows with source zip archive
    • #1559: [core] CPD: Lexical error in file (no file name provided)
    • #1671: [doc] Wrong escaping in suppressing warnings for nopmd-comment
    • #1693: [ui] Improved error reporting for the designer
  • java-bestpractices
    • #808: [java] AccessorMethodGeneration false positives with compile time constants
    • #1405: [java] New Rule: UseTryWithResources - Replace close and IOUtils.closeQuietly with try-with-resources
    • #1555: [java] UnusedImports false positive for method parameter type in @see Javadoc
  • java-codestyle
    • #1543: [java] LinguisticNaming should ignore overriden methods
    • #1547: [java] AtLeastOneConstructorRule: false-positive with lombok.AllArgsConstructor
    • #1624: [java] UseDiamondOperator false positive with var initializer
  • java-design
    • #1641: [java] False-positive with Lombok and inner classes
  • java-errorprone
    • #780: [java] BeanMembersShouldSerializeRule does not recognize lombok accessors
  • java-multithreading
    • #1633: [java] UnsynchronizedStaticFormatter reports commons lang FastDateFormat
  • java-performance
    • #1632: [java] ConsecutiveLiteralAppends false positive over catch
  • plsql
    • #1587: [plsql] ParseException with EXISTS
    • #1589: [plsql] ParseException with subqueries in WHERE clause
    • #1590: [plsql] ParseException when using hierarchical query clause
    • #1656: [plsql] ParseException with analytic functions, trim and subqueries
  • designer
    • #1679: [ui] No default language version selected

API Changes

No changes.

External Contributions

  • #1623: [java] Fix lombok.AllArgsConstructor support - Bobby Wertman
  • #1625: [java] UnusedImports false positive for method parameter type in @see Javadoc - Shubham
  • #1628: [java] LinguisticNaming should ignore overriden methods - Shubham
  • #1634: [java] BeanMembersShouldSerializeRule does not recognize lombok accessors - Shubham
  • #1635: [java] UnsynchronizedStaticFormatter reports commons lang FastDateFormat - Shubham
  • #1637: [java] Compile time constants initialized by literals avoided by AccessorMethodGenerationRule - Shubham
  • #1640: [java] Update instead of override classHasLombokAnnotation flag - Phokham Nonava
  • #1644: [apex] Add property to allow apex test methods to contain underscores - Tom
  • #1645: [java] ConsecutiveLiteralAppends false positive - Shubham
  • #1646: [java] UseDiamondOperator doesn’t work with var - Shubham
  • #1654: [core] Antlr token filter - Tomi De Lucca
  • #1655: [kotlin] Kotlin tokenizer refactor - Lucas Soncini
  • #1686: [doc] Replaced wrong escaping with “>” - Himanshu Pandey

27-January-2019 - 6.11.0

The PMD team is pleased to announce PMD 6.11.0.

This is a minor release.

Table Of Contents

New and noteworthy

Updated Apex Support

  • The Apex language support has been bumped to version 45 (Spring ‘19). All new language features are now properly parsed and processed.
  • Many nodes now expose more informations, such as the operator for BooleanExpressions. This makes these operators consumable by XPath rules, e.g. //BooleanExpression[@Operator='&&'].

PL/SQL Grammar improvements

  • In this release, many parser bugs in our PL/SQL support have been fixed. This adds e.g. support for table collection expressions (SELECT * FROM TABLE(expr)).
  • Support for parsing insert statements has been added.
  • More improvements are planned for the next release of PMD.

New Rules

  • The new Java rule UnsynchronizedStaticFormatter (java-multithreading) detects unsynchronized usages of static java.text.Format instances. This rule is a more generic replacement of the rule UnsynchronizedStaticDateFormatter which focused just on DateFormat.

  • The new Java rule ForLoopVariableCount (java-bestpractices) checks for the number of control variables in a for-loop. Having a lot of control variables makes it harder to understand what the loop does. The maximum allowed number of variables is by default 1 and can be configured by a property.

  • The new Java rule AvoidReassigningLoopVariables (java-bestpractices) searches for loop variables that are reassigned. Changing the loop variables additionally to the loop itself can lead to hard-to-find bugs.

  • The new Java rule UseDiamondOperator (java-codestyle) looks for constructor calls with explicit type parameters. Since Java 1.7, these type parameters are not necessary anymore, as they can be inferred now.

Modified Rules

  • The Java rule LocalVariableCouldBeFinal (java-codestyle) has a new property ignoreForEachDecl, which is by default disabled. The new property allows for ignoring non-final loop variables in a for-each statement.

Deprecated Rules

Fixed Issues

  • core
    • #1196: [core] CPD results not consistent between runs
    • #1496 [core] Refactor metrics to be dealt with generically from pmd-core
  • apex
    • #1542: [apex] Include the documentation category
    • #1546: [apex] PMD parsing exception for Apex classes using ‘inherited sharing’ keyword
    • #1568: [apex] AST node attribute @Image not usable / always null in XPath rule / Designer
  • java
    • #1556: [java] Default methods should not be considered abstract
    • #1578: [java] Private field is detected as public inside nested classes in interfaces
  • java-bestpractices
    • #658: [java] OneDeclarationPerLine: False positive for loops
    • #1518: [java] New rule: AvoidReassigningLoopVariable
    • #1519: [java] New rule: ForLoopVariableCount
  • java-codestyle
    • #1513: [java] LocalVariableCouldBeFinal: allow excluding the variable in a for-each loop
    • #1517: [java] New Rule: UseDiamondOperator
  • java-errorprone
    • #1035: [java] ReturnFromFinallyBlock: False positive on lambda expression in finally block
    • #1549: [java] NPE in PMD 6.8.0 InvalidSlf4jMessageFormat
  • java-multithreading
    • #1533: [java] New rule: UnsynchronizedStaticFormatter
  • plsql
    • #1507: [plsql] Parse Exception when using ‘   ’ operator in where clause
    • #1508: [plsql] Parse Exception when using SELECT COUNT(*)
    • #1509: [plsql] Parse Exception with OUTER/INNER Joins
    • #1511: [plsql] Parse Exception with IS NOT NULL
    • #1526: [plsql] ParseException when using TableCollectionExpression
    • #1583: [plsql] Update Set Clause should allow multiple columns
    • #1586: [plsql] Parse Exception when functions are used with LIKE
    • #1588: [plsql] Parse Exception with function calls in WHERE clause

API Changes

External Contributions

  • #1503: [java] Fix for ReturnFromFinallyBlock false-positives - RishabhDeep Singh
  • #1514: [java] LocalVariableCouldBeFinal: allow excluding the variable in a for-each loop - Kris Scheibe
  • #1516: [java] OneDeclarationPerLine: Don’t report multiple variables in a for statement. - Kris Scheibe
  • #1520: [java] New rule: ForLoopVariableCount: check the number of control variables in a for loop - Kris Scheibe
  • #1521: [java] Upgrade to ASM7 for JDK 11 support - Mark Pritchard
  • #1530: [java] New rule: AvoidReassigningLoopVariables - Kris Scheibe
  • #1534: [java] This is the change regarding the usediamondoperator #1517 - hemanshu070
  • #1545: [doc] fixing dead links + tool to check for dead links automatically - Kris Scheibe
  • #1551: [java] InvalidSlf4jMessageFormatRule should not throw NPE for enums - Robbie Martinus
  • #1552: [core] Upgrading Google Gson from 2.5 to 2.8.5 - Thunderforge
  • #1553: [core] Upgrading System Rules dependency from 1.8.0 to 1.19.0 - Thunderforge
  • #1554: [plsql] updates should allow for multiple statements - tashiscool
  • #1584: [core] Fixes 1196: inconsistencies of clones returned by different CPD executions for the same files - Bruno Ferreira

09-December-2018 - 6.10.0

The PMD team is pleased to announce PMD 6.10.0.

This is a minor release.

Table Of Contents

New and noteworthy

Kotlin support for CPD

Thanks to Maikel Steneker, CPD now supports Kotlin. This means, you can use CPD to find duplicated code in your Kotlin projects.

New Rules

  • The new Java rule UseUnderscoresInNumericLiterals (java-codestyle) verifies that numeric literals over a given length (4 chars by default, but configurable) are using underscores every 3 digits for readability. The rule only applies to Java 7+ codebases.

Modified Rules

Fixed Issues

  • all
    • #1284: [doc] Keep record of every currently deprecated API
    • #1318: [test] Kotlin DSL to ease test writing
    • #1328: [ci] Building docs for release fails
    • #1341: [doc] Documentation Error with Regex Properties
    • #1468: [doc] Missing escaping leads to XSS
    • #1471: [core] XMLRenderer: ProcessingErrors from exceptions without a message missing
    • #1477: [core] Analysis cache fails with wildcard classpath entries
  • java
    • #1460: [java] Intermittent PMD failure : PMD processing errors while no violations reported
  • java-bestpractices
    • #647: [java] JUnitTestsShouldIncludeAssertRule should support this.exception as well as just exception
    • #1435: [java] JUnitTestsShouldIncludeAssert: Support AssertJ soft assertions
  • java-codestyle
    • #1232: [java] Detector for large numbers not separated by _
    • #1372: [java] false positive for UselessQualifiedThis
    • #1440: [java] CommentDefaultAccessModifierRule shows incorrect message
  • java-design
    • #1151: [java] ImmutableField false positive with multiple constructors
    • #1483: [java] Cyclo metric should count conditions of for statements correctly
  • java-errorprone
    • #1512: [java] InvalidSlf4jMessageFormatRule causes NPE in lambda and static blocks
  • plsql
    • #1454: [plsql] ParseException for IF/CASE statement with >=, <=, !=

API Changes

Properties framework

The properties framework is about to get a lifting, and for that reason, we need to deprecate a lot of APIs to remove them in 7.0.0. The proposed changes to the API are described on the wiki

Changes to how you define properties

Here’s an example:

// Before 7.0.0, these are equivalent:
IntegerProperty myProperty = new IntegerProperty("score", "Top score value", 1, 100, 40, 3.0f);
IntegerProperty myProperty = IntegerProperty.named("score").desc("Top score value").range(1, 100).defaultValue(40).uiOrder(3.0f);

// They both map to the following in 7.0.0
PropertyDescriptor<Integer> myProperty = PropertyFactory.intProperty("score").desc("Top score value").require(inRange(1, 100)).defaultValue(40);

You’re highly encouraged to migrate to using this new API as soon as possible, to ease your migration to 7.0.0.

Architectural simplifications
Changes to the PropertyDescriptor interface
  • preferredRowCount is deprecated with no intended replacement. It was never implemented, and does not belong in this interface. The methods uiOrder and compareTo(PropertyDescriptor) are deprecated for the same reason. These methods mix presentation logic with business logic and are not necessary for PropertyDescriptors to work. PropertyDescriptor will not extend Comparable<PropertyDescriptor> anymore come 7.0.0.
  • The method propertyErrorFor is deprecated and will be removed with no intended replacement. It’s really just a shortcut for prop.errorFor(rule.getProperty(prop)).
  • T valueFrom(String) and String asDelimitedString(T) are deprecated and will be removed. These were used to serialize and deserialize properties to/from a string, but 7.0.0 will introduce a more flexible XML syntax which will make them obsolete.
  • isMultiValue and type are deprecated and won’t be replaced. The new XML syntax will remove the need for a divide between multi- and single-value properties, and will allow arbitrary types to be represented. Since arbitrary types may be represented, type will become obsolete as it can’t represent generic types, which will nevertheless be representable with the XML syntax. It was only used for documentation, but a new way to document these properties exhaustively will be added with 7.0.0.
  • errorFor is deprecated as its return type will be changed to Optional<String> with the shift to Java 8.

Deprecated APIs

For internalization
For removal

External Contributions

28-October-2018 - 6.9.0

The PMD team is pleased to announce PMD 6.9.0.

This is a minor release.

Table Of Contents

New and noteworthy

Improved Golang CPD Support

Thanks to the work of ITBA students Matías Fraga, Tomi De Lucca and Lucas Soncini, Golang is now backed by a proper Antlr Grammar. This means CPD is now better at detecting duplicates, as comments are recognized as such and ignored.

New Rules

  • The new PLSQL rule CodeFormat (plsql-codestyle) verifies that PLSQL code is properly formatted. It checks e.g. for correct indentation in select statements and verifies that each parameter is defined on a separate line.

Fixed Issues

  • all
    • #649: [core] Exclude specific files from command line
    • #1272: [core] Could not find or load main class when using symlinked run.sh
    • #1377: [core] LanguageRegistry uses default class loader when invoking ServiceLocator
    • #1394: [doc] How to configure “-cache "
    • #1412: [doc] Broken link to adding new cpd language documentation
  • apex
    • #1396: [apex] ClassCastException caused by Javadoc
  • java
    • #1330: [java] PMD crashes with java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/xml/ws/Service
  • java-bestpractices
    • #1202: [java] GuardLogStatement: “There is log block not surrounded by if” doesn’t sound right
    • #1209: [java] UnusedImports false positive for static import with package-private method usage
    • #1343: [java] Update CommentDefaultAccessModifierRule to extend AbstractIgnoredAnnotationRule
    • #1365: [java] JUnitTestsShouldIncludeAssert false positive
    • #1404: [java] UnusedImports false positive with static ondemand import with method call
  • java-codestyle
    • #1199: [java] UnnecessaryFullyQualifiedName doesn’t flag same package FQCNs
    • #1356: [java] UnnecessaryModifier wrong message public->static
  • java-design
    • #1369: [java] Processing error (ClassCastException) if a TYPE_USE annotation is used on a base class in the “extends” clause
  • jsp
    • #1402: [jsp] JspTokenManager has a problem about jsp scriptlet
  • documentation
    • #1349: [doc] Provide some explanation for WHY duplicate code is bad, like mutations

API Changes

  • PMD has a new CLI option -ignorelist. With that, you can provide a file containing a comma-delimit list of files, that should be excluded during analysis. The ignorelist is applied after the files have been selected via -dir or -filelist, which means, if the file is in both lists, then it will be ignored. Note: there is no corresponding option for the Ant task, since the feature is already available via Ant’s FileSet include/exclude filters.

External Contributions

30-September-2018 - 6.8.0

The PMD team is pleased to announce PMD 6.8.0.

This is a minor release.

Table Of Contents

New and noteworthy

Drawing a line between private and public API

Until now, all released public members and types were implicitly considered part of PMD’s public API, including inheritance-specific members (protected members, abstract methods). We have maintained those APIs with the goal to preserve full binary compatibility between minor releases, only breaking those APIs infrequently, for major releases.

In order to allow PMD to move forward at a faster pace, this implicit contract will be invalidated with PMD 7.0.0. We now introduce more fine-grained distinctions between the type of compatibility support we guarantee for our libraries, and ways to make them explicit to clients of PMD.

.internal packages and @InternalApi annotation

Internal API is meant for use only by the main PMD codebase. Internal types and methods may be modified in any way, or even removed, at any time.

Any API in a package that contains an .internal segment is considered internal. The @InternalApi annotation will be used for APIs that have to live outside of these packages, e.g. methods of a public type that shouldn’t be used outside of PMD (again, these can be removed anytime).

@ReservedSubclassing

Types marked with the @ReservedSubclassing annotation are only meant to be subclassed by classes within PMD. As such, we may add new abstract methods, or remove protected methods, at any time. All published public members remain supported. The annotation is not inherited, which means a reserved interface doesn’t prevent its implementors to be subclassed.

@Experimental

APIs marked with the @Experimental annotation at the class or method level are subject to change. They can be modified in any way, or even removed, at any time. You should not use or rely on them in any production code. They are purely to allow broad testing and feedback.

@Deprecated

APIs marked with the @Deprecated annotation at the class or method level will remain supported until the next major release but it is recommended to stop using them.

The transition

All currently supported APIs will remain so until 7.0.0. All APIs that are to be moved to .internal packages or hidden will be tagged @InternalApi before that major release, and the breaking API changes will be performed in 7.0.0.

Quickstart Ruleset

PMD 6.8.0 provides a first quickstart ruleset for Java, which you can use as a base ruleset to get your custom ruleset started. You can reference it with rulesets/java/quickstart.xml. You are strongly encouraged to create your own ruleset though.

The quickstart ruleset has the intention, to be useful out-of-the-box for many projects. Therefore it references only rules, that are most likely to apply everywhere.

Any feedback would be greatly appreciated.

New Rules

  • The new Apex rule ApexDoc (apex-documentation) enforces the inclusion of ApexDoc on classes, interfaces, properties and methods; as well as some sanity rules for such docs (no missing parameters, parameters’ order, and return value). By default, method overrides and test classes are allowed to not include ApexDoc.

Modified Rules

  • The rule MissingSerialVersionUID (java-errorprone) has been modified in order to recognize also missing serialVersionUID fields in abstract classes, if they are serializable. Each individual class in the inheritance chain needs an own serialVersionUID field. See also Should an abstract class have a serialVersionUID. This change might lead to additional violations in existing code bases.

PLSQL

The grammar for PLSQL has been revamped in order to fully parse SELECT INTO, UPDATE, and DELETE statements. Previously such statements have been simply skipped ahead, now PMD is parsing them, giving access to the individual parts of a SELECT-statement, such as the Where-Clause. This might produce new parsing errors where PMD previously could successfully parse PLSQL code. If this happens, please report a new issue to get this problem fixed.

Fixed Issues

  • apex-bestpractices
    • #1348: [apex] AvoidGlobalModifierRule gives warning even when its a webservice - false positive
  • java-codestyle
    • #1329: [java] FieldNamingConventions: false positive in serializable class with serialVersionUID
    • #1334: [java] LinguisticNaming should support AtomicBooleans
  • java-errorprone
    • #1350: [java] MissingSerialVersionUID false-positive on interfaces
    • #1352: [java] MissingSerialVersionUID false-negative with abstract classes
  • java-performance
    • #1325: [java] False positive in ConsecutiveLiteralAppends
  • plsql
    • #1279: [plsql] Support for SELECT INTO

API Changes

  • A couple of methods and fields in net.sourceforge.pmd.properties.AbstractPropertySource have been deprecated, as they are replaced by already existing functionality or expose internal implementation details: propertyDescriptors, propertyValuesByDescriptor, copyPropertyDescriptors(), copyPropertyValues(), ignoredProperties(), usesDefaultValues(), useDefaultValueFor().

  • Some methods in net.sourceforge.pmd.properties.PropertySource have been deprecated as well: usesDefaultValues(), useDefaultValueFor(), ignoredProperties().

  • The class net.sourceforge.pmd.lang.rule.AbstractDelegateRule has been deprecated and will be removed with PMD 7.0.0. It is internally only in use by RuleReference.

  • The default constructor of net.sourceforge.pmd.lang.rule.RuleReference has been deprecated and will be removed with PMD 7.0.0. RuleReferences should only be created by providing a Rule and a RuleSetReference. Furthermore the following methods are deprecated: setRuleReference(), hasOverriddenProperty(), usesDefaultValues(), useDefaultValueFor().

External Contributions

02-September-2018 - 6.7.0

The PMD team is pleased to announce PMD 6.7.0.

This is a minor release.

Table Of Contents

New and noteworthy

Modified Rules

  • The Java rule OneDeclarationPerLine (java-bestpractices) has been revamped to consider not only local variable declarations, but field declarations too.

New Rules

  • The new Java rule LinguisticNaming (java-codestyle) detects cases, when a method name indicates it returns a boolean (such as isSmall()) but it doesn’t. Besides method names, the rule also checks field and variable names. It also checks, that getters return something but setters won’t. The rule has several properties with which it can be customized.

  • The new PL/SQL rule ForLoopNaming (plsql-codestyle) enforces a naming convention for “for loops”. Both “cursor for loops” and “index for loops” are covered. The rule can be customized via patterns. By default, short variable names are reported.

  • The new Java rule FieldNamingConventions (java-codestyle) detects field names that don’t comply to a given convention. It defaults to standard Java convention of using camelCase, but can be configured with ease for e.g. constants or static fields.

  • The new Apex rule OneDeclarationPerLine (apex-codestyle) enforces declaring a single field / variable per line; or per statement if the strictMode property is set. It’s an Apex equivalent of the already existing Java rule of the same name.

Deprecated Rules

Fixed Issues

  • core
    • #1191: [core] Test Framework: Sort violations by line/column
    • #1283: [core] Deprecate ReportTree
    • #1288: [core] No supported build listeners found with Gradle
    • #1300: [core] PMD stops processing file completely, if one rule in a rule chain fails
    • #1317: [ci] Coveralls hasn’t built the project since June 25th
  • java-bestpractices
    • #940: [java] JUnit 4 false positives for JUnit 5 tests
    • #1267: [java] MissingOverrideRule: Avoid NoClassDefFoundError with incomplete classpath
    • #1323: [java] AvoidUsingHardCodedIP ignores match pattern
    • #1327: [java] AvoidUsingHardCodedIP false positive for “:bee”
  • java-codestyle
    • #1255: [java] UnnecessaryFullyQualifiedName false positive: static method on shadowed implicitly imported class
    • #1258: [java] False positive “UselessParentheses” for parentheses that contain assignment
  • java-errorprone
    • #1078: [java] MissingSerialVersionUID rule does not seem to catch inherited classes
  • java-performance
    • #1291: [java] InvalidSlf4jMessageFormat false positive: too many arguments with string concatenation operator
    • #1298: [java] RedundantFieldInitializer - NumberFormatException with Long
  • jsp
    • #1274: [jsp] Support EL in tag attributes
    • #1276: [jsp] add support for jspf and tag extensions
  • plsql
    • #681: [plsql] Parse error with Cursor For Loop

API Changes

  • All classes in the package net.sourceforge.pmd.lang.dfa.report have been deprecated and will be removed with PMD 7.0.0. This includes the class net.sourceforge.pmd.lang.dfa.report.ReportTree. The reason is, that this class is very specific to Java and not suitable for other languages. It has only been used for YAHTMLRenderer, which has been rewritten to work without these classes.

  • The nodes RUNSIGNEDSHIFT and RSIGNEDSHIFT are deprecated and will be removed from the AST with PMD 7.0.0. These represented the operator of ShiftExpression in two cases out of three, but they’re not needed and make ShiftExpression inconsistent. The operator of a ShiftExpression is now accessible through ShiftExpression#getOperator.

External Contributions

  • #109: [java] Add two linguistics rules under naming - Arda Aslan
  • #1254: [ci] [GSoC] Integrating the danger and pmdtester to travis CI - BBG
  • #1258: [java] Use typeof in MissingSerialVersionUID - krichter722
  • #1264: [cpp] Fix NullPointerException in CPPTokenizer:99 - Rafael Cortês
  • #1277: [jsp] #1276 add support for jspf and tag extensions - Jordi Llach
  • #1275: [jsp] Issue #1274 - Support EL in tag attributes - Jordi Llach
  • #1278: [ci] [GSoC] Use pmdtester 1.0.0.pre.beta3 - BBG
  • #1289: [java] UselessParentheses: Fix false positive with assignments - cobratbq
  • #1290: [docs] [GSoC] Create the documentation about pmdtester - BBG
  • #1256: [java] #940 Avoid JUnit 4 false positives for JUnit 5 tests - Alex Shesterov
  • #1315: [apex] Add OneDeclarationPerStatement rule - Jeff Hube

29-July-2018 - 6.6.0

The PMD team is pleased to announce PMD 6.6.0.

This is a minor release.

Table Of Contents

New and noteworthy

Java 11 Support

PMD is now able to parse the local-variable declaration syntax var xxx, that has been extended for lambda parameters with Java 11 via JEP 323: Local-Variable Syntax for Lambda Parameters.

New Rules

  • The new Java rule LocalVariableNamingConventions (java-codestyle) detects local variable names that don’t comply to a given convention. It defaults to standard Java convention of using camelCase, but can be configured. Special cases can be configured for final variables and caught exceptions’ names.

  • The new Java rule FormalParameterNamingConventions (java-codestyle) detects formal parameter names that don’t comply to a given convention. It defaults to standard Java convention of using camelCase, but can be configured. Special cases can be configured for final parameters and lambda parameters (considering whether they are explicitly typed or not).

Modified Rules

Fixed Issues

  • core
    • #1178: [core] “Unsupported build listener” in gradle build
    • #1225: [core] Error in sed expression on line 82 of run.sh while detecting installed version of Java
  • doc
    • #1215: [doc] TOC links don’t work?
  • java-codestyle
    • #1211: [java] CommentDefaultAccessModifier false positive with nested interfaces (regression from 6.4.0)
    • #1216: [java] UnnecessaryFullyQualifiedName false positive for the same name method
  • java-design
    • #1217: [java] CyclomaticComplexityRule counts ?-operator twice
    • #1226: [java] NPath complexity false negative due to overflow
  • plsql
    • #980: [plsql] ParseException for CREATE TABLE
    • #981: [plsql] ParseException when parsing VIEW
    • #1047: [plsql] ParseException when parsing EXECUTE IMMEDIATE
  • ui
    • #1233: [ui] XPath autocomplete arrows on first and last items

API Changes

  • The findDescendantsOfType methods in net.sourceforge.pmd.lang.ast.AbstractNode no longer search for exact type matches, but will match subclasses, too. That means, it’s now possible to look for abstract node types such as AbstractJavaTypeNode and not only for it’s concrete subtypes.

External Contributions

26-June-2018 - 6.5.0

The PMD team is pleased to announce PMD 6.5.0.

This is a minor release.

Table Of Contents

New and noteworthy

New Rules

  • The new Apex rule AvoidNonExistentAnnotations (apex-errorprone) detects usages non-officially supported annotations. Apex supported non existent annotations for legacy reasons. In the future, use of such non-existent annotations could result in broken Apex code that will not compile. A full list of supported annotations can be found here

Modified Rules

  • The Java rule UnnecessaryModifier (java-codestyle) now detects enum constrcutors with explicit private modifier. The rule now produces better error messages letting you know exactly which modifiers are redundant at each declaration.

Fixed Issues

  • all
    • #1119: [doc] Make the landing page of the documentation website more useful
    • #1168: [core] xml renderer schema definitions (#538) break included xslt files
    • #1173: [core] Some characters in CPD are not shown correctly.
    • #1193: [core] Designer doesn’t start with run.sh
  • ecmascript
    • #861: [ecmascript] InnaccurateNumericLiteral false positive with hex literals
  • java
    • #1074: [java] MissingOverrideRule exception when analyzing PMD under Java 9
    • #1174: [java] CommentUtil.multiLinesIn() could lead to StringIndexOutOfBoundsException
  • java-bestpractices
    • #651: [java] SwitchStmtsShouldHaveDefault should be aware of enum types
    • #869: [java] GuardLogStatement false positive on return statements and Math.log
  • java-codestyle
    • #667: [java] Make AtLeastOneConstructor Lombok-aware
    • #1154: [java] CommentDefaultAccessModifierRule FP with nested enums
    • #1158: [java] Fix IdenticalCatchBranches false positive
    • #1186: [java] UnnecessaryFullyQualifiedName doesn’t detect java.lang FQ names as violations
  • java-design
    • #1200: [java] New default NcssCount method report level is drastically reduced from values of deprecated NcssMethodCount and NcssTypeCount
  • xml
    • #715: [xml] ProjectVersionAsDependencyVersion false positive

API Changes

  • The utility class net.sourceforge.pmd.lang.java.ast.CommentUtil has been deprecated and will be removed with PMD 7.0.0. Its methods have been intended to parse javadoc tags. A more useful solution will be added around the AST node FormalComment, which contains as children JavadocElement nodes, which in turn provide access to the JavadocTag.

    All comment AST nodes (FormalComment, MultiLineComment, SingleLineComment) have a new method getFilteredComment() which provide access to the comment text without the leading /* markers.

  • The method AbstractCommentRule.tagsIndicesIn() has been deprecated and will be removed with PMD 7.0.0. It is not very useful, since it doesn’t extract the information in a useful way. You would still need check, which tags have been found, and with which data they might be accompanied.

External Contributions

29-May-2018 - 6.4.0

The PMD team is pleased to announce PMD 6.4.0.

This is a minor release.

Table Of Contents

New and noteworthy

Java 10 Support

PMD is now able to understand local-variable type inference as introduced by Java 10. Simple type resolution features are available, e.g. the type of the variable s is inferred correctly as String:

var s = "Java 10";

XPath Type Resolution Functions

For some time now PMD has supported Type Resolution, and exposed this functionality to XPath rules for the Java language with the typeof function. This function however had a number of shortcomings:

  • It would take a first arg with the name to match if types couldn’t be resolved. In all cases this was @Image but was still required.
  • It required 2 separate arguments for the Fully Qualified Class Name and the simple name of the class against which to test.
  • If only the Fully Qualified Class Name was provided, no simple name check was performed (not documented, but abused on some rules to “fix” some false positives).

In this release we are deprecating typeof in favor of a simpler typeIs function, which behaves exactly as the old typeof when given all 3 arguments.

typeIs receives a single parameter, which is the fully qualified name of the class to test against.

So, calls such as:

//ClassOrInterfaceType[typeof(@Image, 'junit.framework.TestCase', 'TestCase')]

can now we expressed much more concisely as:

//ClassOrInterfaceType[typeIs('junit.framework.TestCase')]

With this change, we also allow to check against array types by just appending [] to the fully qualified class name. These can be repeated for arrays of arrays (e.g. byte[][] or java.lang.String[]).

Additionally, we introduce the companion function typeIsExactly, that receives the same parameters as typeIs, but checks for exact type matches, without considering the type hierarchy. That is, the test typeIsExactly('junit.framework.TestCase') will match only if the context node is an instance of TestCase, but not if it’s an instance of a subclass of TestCase. Be aware then, that using that method with abstract types will never match.

New Rules

  • The new Java rule HardCodedCryptoKey (java-security) detects hard coded keys used for encryption. It is recommended to store keys outside of the source code.

  • The new Java rule IdenticalCatchBranches (java-codestyle) finds catch blocks, that catch different exception but perform the same exception handling and thus can be collapsed into a multi-catch try statement.

Modified Rules

  • The Java rule JUnit4TestShouldUseTestAnnotation (java-bestpractices) has a new parameter “testClassPattern”. It is used to distinguish test classes from other classes and avoid false positives. By default, any class, that has “Test” in its name, is considered a test class.

  • The Java rule CommentDefaultAccessModifier (java-codestyle) allows now by default the comment “/* package */ in addition to “/* default */. This behavior can still be adjusted by setting the property regex.

Fixed Issues

  • all
    • #1018: [java] Performance degradation of 250% between 6.1.0 and 6.2.0
    • #1145: [core] JCommander’s help text for option -min is wrong
  • java
    • #672: [java] Support exact type matches for type resolution from XPath
    • #743: [java] Prepare for Java 10
    • #1077: [java] Analyzing enum with lambda passed in constructor fails with “The enclosing scope must exist.”
    • #1115: [java] Simplify xpath typeof syntax
    • #1131: [java] java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/faces/application/FacesMessage$Severity
  • java-bestpractices
    • #527: [java] False Alarm of JUnit4TestShouldUseTestAnnotation on Predicates
    • #1063: [java] MissingOverride is triggered in illegal places
  • java-codestyle
    • #720: [java] ShortVariable should whitelist lambdas
    • #955: [java] Detect identical catch statements
    • #1114: [java] Star import overwritten by explicit import is not correctly handled
    • #1064: [java] ClassNamingConventions suggests to add Util suffix for simple exception wrappers
    • #1065: [java] ClassNamingConventions shouldn’t prohibit numbers in class names
    • #1067: [java] [6.3.0] PrematureDeclaration false-positive
    • #1096: [java] ClassNamingConventions is too ambitious on finding utility classes
  • java-design
    • #824: [java] UseUtilityClass false positive when extending
    • #1021: [java] False positive for DoNotExtendJavaLangError
    • #1097: [java] False negative in AvoidThrowingRawExceptionTypes
  • java-performance
    • #1051: [java] ConsecutiveAppendsShouldReuse false-negative
    • #1098: [java] Simplify LongInstantiation, IntegerInstantiation, ByteInstantiation, and ShortInstantiation using type resolution
    • #1125: [java] Improve message of InefficientEmptyStringCheck for String.trim().isEmpty()
  • doc
    • #999: [doc] Add a header before the XPath expression in rules
    • #1082: [doc] Multifile analysis doc is invalid
  • vf-security
    • #1100: [vf] URLENCODE is ignored as valid escape method

API Changes

  • The following classes in package net.sourceforge.pmd.benchmark have been deprecated: Benchmark, Benchmarker, BenchmarkReport, BenchmarkResult, RuleDuration, StringBuilderCR and TextReport. Their API is not supported anymore and is disconnected from the internals of PMD. Use the newer API based around TimeTracker instead, which can be found in the same package.
  • The class net.sourceforge.pmd.lang.java.xpath.TypeOfFunction has been deprecated. Use the newer TypeIsFunction in the same package.
  • The typeof methdos in net.sourceforge.pmd.lang.java.xpath.JavaFunctions have been deprecated. Use the newer typeIs method in the same class instead..
  • The methods isA, isEither and isNeither of net.sourceforge.pmd.lang.java.typeresolution.TypeHelper. Use the new isExactlyAny and isExactlyNone methods in the same class instead.

External Contributions

29-April-2018 - 6.3.0

The PMD team is pleased to announce PMD 6.3.0.

This is a minor release.

Table Of Contents

New and noteworthy

Tree Traversal Revision

As described in #904, when searching for child nodes of the AST methods such as hasDescendantOfType, getFirstDescendantOfType and findDescendantsOfType were found to behave inconsistently, not all of them honoring find boundaries; that is, nodes that define a self-contained entity which should be considered separately (think of lambdas, nested classes, anonymous classes, etc.). We have modified these methods to ensure all of them honor find boundaries.

This change implies several false positives / unexpected results (ie: ASTBlockStatement falsely returning true to isAllocation()) have been fixed; and lots of searches are now restricted to smaller search areas, which improves performance (depending on the project, we have measured up to 10% improvements during Type Resolution, Symbol Table analysis, and some rules’ application).

Naming Rules Enhancements

  • ClassNamingConventions (java-codestyle) has been enhanced to allow granular configuration of naming conventions for different kinds of type declarations (eg enum or abstract class). Each kind of declaration can use its own naming convention using a regex property. See the rule’s documentation for more info about configuration and default conventions.

  • MethodNamingConventions (java-codestyle) has been enhanced in the same way.

CPD Suppression

Back in PMD 5.6.0 we introduced the ability to suppress CPD warnings in Java using comments, by including CPD-OFF (to start ignoring code), or CPD-ON (to resume analysis) during CPD execution. This has proved to be much more flexible and versatile than the old annotation-based approach, and has since been the preferred way to suppress CPD warnings.

On this occasion, we are extending support for comment-based suppressions to many other languages:

  • C/C++
  • Ecmascript / Javascript
  • Matlab
  • Objective-C
  • PL/SQL
  • Python

So for instance, in Python we could now do:

class BaseHandler(object):
    def __init__(self):
        # some unignored code

        # tell cpd to start ignoring code - CPD-OFF

        # mission critical code, manually loop unroll
        GoDoSomethingAwesome(x + x / 2);
        GoDoSomethingAwesome(x + x / 2);
        GoDoSomethingAwesome(x + x / 2);
        GoDoSomethingAwesome(x + x / 2);
        GoDoSomethingAwesome(x + x / 2);
        GoDoSomethingAwesome(x + x / 2);

        # resume CPD analysis - CPD-ON

        # further code will *not* be ignored

Other languages are equivalent.

Swift 4.1 Support

Thanks to major contributions from kenji21 the Swift grammar has been updated to support Swift 4.1. This is a major update, since the old grammar was quite dated, and we are sure all iOS developers will enjoy it.

Unfortunately, this change is not compatible. The grammar elements that have been removed (ie: the keywords __FILE__, __LINE__, __COLUMN__ and __FUNCTION__) are no longer supported. We don’t usually introduce such drastic / breaking changes in minor releases, however, given that the whole Swift ecosystem pushes hard towards always using the latest versions, and that Swift needs all code and libraries to be currently compiling against the same Swift version, we felt strongly this change was both safe and necessary to be shipped as soon as possible. We had great feedback from the community during the process but if you have a legitimate use case for older Swift versions, please let us know on our Issue Tracker.

New Rules

  • The new Java rule InsecureCryptoIv (java-security) detects hard coded initialization vectors used in cryptographic operations. It is recommended to use a randomly generated IV.

Modified Rules

  • The Java rule UnnecessaryConstructor (java-codestyle) has been rewritten as a Java rule (previously it was a XPath-based rule). It supports a new property ignoredAnnotations and ignores by default empty constructors, that are annotated with javax.inject.Inject. Additionally, it detects now also unnecessary private constructors in enums.

  • The property checkNativeMethods of the Java rule MethodNamingConventions (java-codestyle) is now deprecated, as it is now superseded by nativePattern. Support for that property will be maintained until 7.0.0.

  • The Java rule ControlStatementBraces (java-codestyle) supports a new boolean property checkSingleIfStmt. When unset, the rule won’t report if statements which lack braces, if the statement is not part of an if ... else if chain. This property defaults to true.

Deprecated Rules

Fixed Issues

  • all
    • #695: [core] Extend comment-based suppression to all JavaCC languages
    • #988: [core] FileNotFoundException for missing classes directory with analysis cache enabled
    • #1036: [core] Non-XML output breaks XML-based CLI integrations
  • apex-errorprone
    • #776: [apex] AvoidHardcodingId false positives
  • documentation
    • #994: [doc] Delete duplicate page contributing.md on the website
    • #1057: [doc] Documentation of ignoredAnnotations property is misleading
  • java
    • #894: [java] Maven PMD plugin fails to process some files without any explanation
    • #899: [java] JavaTypeDefinitionSimple.toString can cause NPEs
    • #1020: [java] The CyclomaticComplexity rule runs forever in 6.2.0
    • #1030: [java] NoClassDefFoundError when analyzing PMD with PMD
    • #1061: [java] Update ASM to handle Java 10 bytecode
  • java-bestpractices
    • #370: [java] GuardLogStatementJavaUtil not considering lambdas
    • #558: [java] ProperLogger Warnings for enums
    • #719: [java] Unused Code: Java 8 receiver parameter with an internal class
    • #1009: [java] JUnitAssertionsShouldIncludeMessage - False positive with assertEquals and JUnit5
  • java-codestyle
    • #1003: [java] UnnecessaryConstructor triggered on required empty constructor (Dagger @Inject)
    • #1023: [java] False positive for useless parenthesis
    • #1004: [java] ControlStatementBraces is missing checkIfStmt property
  • java-design
    • #1056: [java] Property ignoredAnnotations does not work for SingularField and ImmutableField
  • java-errorprone
    • #629: [java] NullAssignment false positive
    • #816: [java] SingleMethodSingleton false positives with inner classes
  • java-performance
    • #586: [java] AvoidUsingShortType erroneously triggered on overrides of 3rd party methods
  • swift
    • #678: [swift][cpd] Exception when running for Swift 4 code (KeyPath)

External Contributions

26-March-2018 - 6.2.0

The PMD team is pleased to announce PMD 6.2.0.

This is a minor release.

Table Of Contents

New and noteworthy

Ecmascript (JavaScript)

The Rhino Library has been upgraded from version 1.7.7 to version 1.7.7.2.

Detailed changes for changed in Rhino can be found:

Both are bugfixing releases.

Disable Incremental Analysis

Some time ago, we added support for Incremental Analysis. On PMD 6.0.0, we started to add warns when not using it, as we strongly believe it’s a great improvement to our user’s experience as analysis time is greatly reduced; and in the future we plan to have it enabled by default. However, we realize some scenarios don’t benefit from it (ie: CI jobs), and having the warning logged can be noisy and cause confusion.

To this end, we have added a new flag to allow you to explicitly disable incremental analysis. On CLI, this is the new -no-cache flag. On Ant, there is a noCache attribute for the <pmd> task.

On both scenarios, disabling the cache takes precedence over setting a cache location.

New Rules

  • The new Java rule MissingOverride (category bestpractices) detects overridden and implemented methods, which are not marked with the @Override annotation. Annotating overridden methods with @Override ensures at compile time that the method really overrides one, which helps refactoring and clarifies intent.

  • The new Java rule UnnecessaryAnnotationValueElement (category codestyle) detects annotations with a single element (value) that explicitely names it. That is, doing @SuppressWarnings(value = "unchecked") would be flagged in favor of @SuppressWarnings("unchecked").

  • The new Java rule ControlStatementBraces (category codestyle) enforces the presence of braces on control statements where they are optional. Properties allow to customize which statements are required to have braces. This rule replaces the now deprecated rules WhileLoopMustUseBraces, ForLoopMustUseBraces, IfStmtMustUseBraces, and IfElseStmtMustUseBraces. More than covering the use cases of those rules, this rule also supports do ... while statements and case labels of switch statements (disabled by default).

Modified Rules

  • The Java rule CommentContentRule (java-documentation) previously had the property wordsAreRegex. But this property never had been implemented and is removed now.

  • The Java rule UnusedPrivateField (java-bestpractices) now has a new ignoredAnnotations property that allows to configure annotations that imply the field should be ignored. By default @java.lang.Deprecated and @javafx.fxml.FXML are ignored.

  • The Java rule UnusedPrivateMethod (java-bestpractices) now has a new ignoredAnnotations property that allows to configure annotations that imply the method should be ignored. By default @java.lang.Deprecated is ignored.

  • The Java rule ImmutableField (java-design) now has a new ignoredAnnotations property that allows to configure annotations that imply the method should be ignored. By default several lombok annotations are ignored

  • The Java rule SingularField (java-design) now has a new ignoredAnnotations property that allows to configure annotations that imply the method should be ignored. By default several lombok annotations are ignored

Deprecated Rules

  • The Java rules WhileLoopMustUseBraces, ForLoopMustUseBraces, IfStmtMustUseBraces, and IfElseStmtMustUseBraces are deprecated. They will be replaced by the new rule ControlStatementBraces, in the category codestyle.

Fixed Issues

  • all
    • #928: [core] PMD build failure on Windows
  • java-bestpracrtices
    • #907: [java] UnusedPrivateField false-positive with @FXML
    • #963: [java] ArrayIsStoredDirectly not triggered from variadic functions
  • java-codestyle
    • #974: [java] Merge *StmtMustUseBraces rules
    • #983: [java] Detect annotations with single value element
  • java-design
    • #832: [java] AvoidThrowingNullPointerException documentation suggestion
    • #837: [java] CFGs of declared but not called lambdas are treated as parts of an enclosing method’s CFG
    • #839: [java] SignatureDeclareThrowsException’s IgnoreJUnitCompletely property not honored for constructors
    • #968: [java] UseUtilityClassRule reports false positive with lombok NoArgsConstructor
  • documentation
    • #978: [core] Broken link in CONTRIBUTING.md
    • #992: [core] Include info about rule doc generation in “Writing Documentation” md page

API Changes

  • A new CLI switch, -no-cache, disables incremental analysis and the related suggestion. This overrides the -cache option. The corresponding Ant task parameter is noCache.

  • The static method PMDParameters.transformParametersIntoConfiguration(PMDParameters) is now deprecated, for removal in 7.0.0. The new instance method PMDParameters.toConfiguration() replaces it.

  • The method ASTConstructorDeclaration.getParameters() has been deprecated in favor of the new method getFormalParameters(). This method is available for both ASTConstructorDeclaration and ASTMethodDeclaration.

External Contributions

  • #941: [java] Use char notation to represent a character to improve performance - reudismam
  • #943: [java] UnusedPrivateField false-positive with @FXML - BBG
  • #951: [java] Add ignoredAnnotations property to unusedPrivateMethod rule - BBG
  • #952: [java] SignatureDeclareThrowsException’s IgnoreJUnitCompletely property not honored for constructors - BBG
  • #958: [java] Refactor how we ignore annotated elements in rules - BBG
  • #965: [java] Make Varargs trigger ArrayIsStoredDirectly - Stephen
  • #967: [doc] Issue 959: fixed broken link to XPath Rule Tutorial - Andrey Mochalov
  • #969: [java] Issue 968 Add logic to handle lombok private constructors with utility classes - Kirk Clemens
  • #970: [java] Fixed inefficient use of keySet iterator instead of entrySet iterator - Andrey Mochalov
  • #984: [java] issue983 Add new UnnecessaryAnnotationValueElement rule - Kirk Clemens
  • #989: [core] Update Contribute.md to close Issue #978 - Bolarinwa Saheed Olayemi
  • #990: [java] Updated Doc on AvoidThrowingNullPointerException to close Issue #832 - Bolarinwa Saheed Olayemi
  • #993: [core] Update writing_documentation.md to fix Issue #992 - Bolarinwa Saheed Olayemi

25-February-2018 - 6.1.0

The PMD team is pleased to announce PMD 6.1.0.

This is a minor release.

Table Of Contents

New and noteworthy

Designer UI

The Designer now supports configuring properties for XPath based rule development. The Designer is still under development and any feedback is welcome.

You can start the designer via run.sh designer or designer.bat.

Fixed Issues

  • all
    • #569: [core] XPath support requires specific toString implementations
    • #795: [cpd] java.lang.OutOfMemoryError
    • #848: [doc] Test failures when building pmd-doc under Windows
    • #872: [core] NullPointerException at FileDataSource.glomName()
    • #854: [ci] Use Java9 for building PMD
  • doc
    • #791: [doc] Documentation site reorganisation
    • #891: [doc] Apex @SuppressWarnings should use single quotes instead of double quotes
    • #909: [doc] Please add new PMD Eclipse Plugin to tool integration section
  • java
    • #825: [java] Excessive*Length ignores too much
    • #888: [java] ParseException occurs with valid ‘<>’ in Java 1.8 mode
    • #920: [java] Update valid identifiers in grammar
  • java-bestpractices
    • #784: [java] ForLoopCanBeForeach false-positive
    • #925: [java] UnusedImports false positive for static import
  • java-design
    • #855: [java] ImmutableField false-positive with lambdas
  • java-documentation
    • #877: [java] CommentRequired valid rule configuration causes PMD error
  • java-errorprone
    • #885: [java] CompareObjectsWithEqualsRule trigger by enum1 != enum2
  • java-performance
    • #541: [java] ConsecutiveLiteralAppends with types other than string
  • scala
    • #853: [scala] Upgrade scala version to support Java 9
  • xml
    • #739: [xml] IllegalAccessException when accessing attribute using Saxon on JRE 9

API Changes

Changes to the Node interface

The method getXPathNodeName is added to the Node interface, which removes the use of the toString of a node to get its XPath element name (see #569). A default implementation is provided in AbstractNode, to stay compatible with existing implementors.

The toString method of a Node is not changed for the time being, and still produces the name of the XPath node. That behaviour may however change in future major releases, e.g. to produce a more useful message for debugging.

Changes to CPD renderers

The interface net.sourceforge.pmd.cpd.Renderer has been deprecated. A new interface net.sourceforge.pmd.cpd.renderer.CPDRenderer has been introduced to replace it. The main difference is that the new interface is meant to render directly to a java.io.Writer rather than to a String. This allows to greatly reduce the memory footprint of CPD, as on large projects, with many duplications, it was causing OutOfMemoryErrors (see #795).

net.sourceforge.pmd.cpd.FileReporter has also been deprecated as part of this change, as it’s no longer needed.

External Contributions

21-January-2018 - 6.0.1

The PMD team is pleased to announce PMD 6.0.1.

This is a bug fixing release.

Table Of Contents

Additional information about the new introduced rule categories

With the release of PMD 6.0.0, all rules have been sorted into one of the following eight categories:

  1. Best Practices: These are rules which enforce generally accepted best practices.
  2. Code Style: These rules enforce a specific coding style.
  3. Design: Rules that help you discover design issues.
  4. Documentation: These rules are related to code documentation.
  5. Error Prone: Rules to detect constructs that are either broken, extremely confusing or prone to runtime errors.
  6. Multithreading: These are rules that flag issues when dealing with multiple threads of execution.
  7. Performance: Rules that flag suboptimal code.
  8. Security: Rules that flag potential security flaws.

Please note, that not every category in every language may have a rule. There might be categories with no rules at all, such as category/java/security.xml, which has currently no rules. There are even languages, which only have rules of one category (e.g. category/xml/errorprone.xml).

You can find the information about available rules in the generated rule documentation, available at https://pmd.github.io/6.0.1/.

In order to help migrate to the new category scheme, the new name for the old, deprecated rule names will be logged as a warning. See PR #865. Please note, that the deprecated rule names will keep working throughout PMD 6. You can upgrade to PMD 6 without the immediate need to migrate your current ruleset. That backwards compatibility will be maintained until PMD 7.0.0 is released.

Fixed Issues

  • all
    • #842: [core] Use correct java bootclasspath for compiling
  • apex-errorprone
    • #792: [apex] AvoidDirectAccessTriggerMap incorrectly detects array access in classes
  • apex-security
    • #788: [apex] Method chaining breaks ApexCRUDViolation
  • doc
    • #782: [doc] Wrong information in the Release Notes about the Security ruleset
    • #794: [doc] Broken documentation links for 6.0.0
  • java
    • #793: [java] Parser error with private method in nested classes in interfaces
    • #814: [java] UnsupportedClassVersionError is failure instead of a warning
    • #831: [java] StackOverflow in JavaTypeDefinitionSimple.toString
  • java-bestpractices
    • #783: [java] GuardLogStatement regression
    • #800: [java] ForLoopCanBeForeach NPE when looping on this object
  • java-codestyle
    • #817: [java] UnnecessaryModifierRule crashes on valid code
  • java-design
    • #785: [java] NPE in DataClass rule
    • #812: [java] Exception applying rule DataClass
    • #827: [java] GodClass crashes with java.lang.NullPointerException
  • java-performance
    • #841: [java] InsufficientStringBufferDeclaration NumberFormatException
  • java-typeresolution
    • #866: [java] rulesets/java/typeresolution.xml lists non-existent rules

API Changes

  • The constant net.sourceforge.pmd.PMD.VERSION has been deprecated and will be removed with PMD 7.0.0. Please use net.sourceforge.pmd.PMDVersion.VERSION instead.

External Contributions

15-December-2017 - 6.0.0

The PMD team is pleased to announce PMD 6.0.0.

This is a major release.

Table Of Contents

New and noteworthy

New Rule Designer

Thanks to Clément Fournier, we now have a new rule designer GUI, which is based on JavaFX. It replaces the old designer and can be started via

  • bin/run.sh designer (on Unix-like platform such as Linux and Mac OS X)
  • bin\designer.bat (on Windows)

Note: At least Java8 is required for the designer. The old designer is still available as designerold but will be removed with the next major release.

Java 9 support

The Java grammar has been updated to support analyzing Java 9 projects:

  • private methods in interfaces are possible
  • The underscore “_” is considered an invalid identifier
  • Diamond operator for anonymous classes
  • The module declarations in module-info.java can be parsed
  • Concise try-with-resources statements are supported

Java 9 support is enabled by default. You can switch back to an older java version via the command line, e.g. -language java -version 1.8.

Revamped Apex CPD

We are now using the Apex Jorje Lexer to tokenize Apex code for CPD. This change means:

  • All comments are now ignored for CPD. This is consistent with how other languages such as Java and Groovy work.
  • Tokenization honors the language specification, which improves accuracy.

CPD will therefore have less false positives and false negatives.

Java Type Resolution

As part of Google Summer of Code 2017, Bendegúz Nagy worked on type resolution for Java. For this release he has extended support for method calls for both instance and static methods.

Method shadowing and overloading are supported, as are varargs. However, the selection of the target method upon the presence of generics and type inference is still work in progress. Expect it in forecoming releases.

As for fields, the basic support was in place for release 5.8.0, but has now been expanded to support static fields.

Metrics Framework

As part of Google Summer of Code 2017, Clément Fournier is worked on the new metrics framework for object-oriented metrics.

There are already a couple of metrics (e.g. ATFD, WMC, Cyclo, LoC) implemented. More metrics are planned. Based on those metrics, rules like “GodClass” detection could be implemented more easily. The following rules benefit from the metrics framework: NcssCount (java), NPathComplexity (java), CyclomaticComplexity (both java and apex).

The Metrics framework has been abstracted and is available in pmd-core for other languages. With this PMD release, the metrics framework is supported for both Java and Apex.

Error Reporting

A number of improvements on error reporting have taken place, meaning changes to some of the report formats.

Also of note, the xml report now provides a XML Schema definition, allowing easier parsing and validation.

Processing Errors

Processing errors can now provide not only the message previously included on some reports, but also a full stacktrace. This will allow better error reports when providing feedback to the PMD team and help in debugging issues.

The report formats providing full stacktrace of errors are:

  • html
  • summaryhtml
  • textcolor
  • vbhtml
  • xml
Configuration Errors

For a long time reports have been notified of configuration errors on rules, but they have remained hidden. On a push to make these more evident to users, and help them get the best results out of PMD, we have started to include them on the reports.

So far, only reports that include processing errors are showing configuration errors. In other words, the report formats providing configuration error reporting are:

  • csv
  • html
  • summaryhtml
  • text
  • textcolor
  • vbhtml
  • xml

As we move forward we will be able to detect and report more configuration errors (ie: incomplete auxclasspath) and include them to such reports.

Apex Rule Suppression

Apex violations can now be suppressed very similarly to how it’s done in Java, by making use of a @SuppressWarnings annotation.

Supported syntax includes:

@SupressWarnings('PMD') // to supress all Apex rules
@SupressWarnings('all') // to supress all Apex rules
@SupressWarnings('PMD.ARuleName') // to supress only the rule named ARuleName
@SupressWarnings('PMD.ARuleName, PMD.AnotherRuleName') // to supress only the rule named ARuleName or AnotherRuleName

Notice this last scenario is slightly different to the Java syntax. This is due to differences in the Apex grammar for annotations.

Rule Categories

All built-in rules have been sorted into one of eight categories:

  1. Best Practices: These are rules which enforce generally accepted best practices.
  2. Code Style: These rules enforce a specific coding style.
  3. Design: Rules that help you discover design issues.
  4. Documentation: These rules are related to code documentation.
  5. Error Prone: Rules to detect constructs that are either broken, extremely confusing or prone to runtime errors.
  6. Multithreading: These are rules that flag issues when dealing with multiple threads of execution.
  7. Performance: Rules that flag suboptimal code.
  8. Security: Rules that flag potential security flaws.

These categories help you to find rules and figure out the relevance and impact for your project.

All rules have been moved accordingly, e.g. the rule “JumbledIncrementer”, which was previously defined in the ruleset “java-basic” has now been moved to the “Error Prone” category. The new rule reference to be used is <rule ref="category/java/errorprone.xml/JumbledIncrementer"/>.

The old rulesets like “java-basic” are still kept for backwards-compatibility but will be removed eventually. The rule reference documentation has been updated to reflect these changes.

New Rules

  • The new Java rule NcssCount (category design) replaces the three rules “NcssConstructorCount”, “NcssMethodCount”, and “NcssTypeCount”. The new rule uses the metrics framework to achieve the same. It has two properties, to define the report level for method and class sizes separately. Constructors and methods are considered the same.

  • The new Java rule DoNotExtendJavaLangThrowable (category errorprone) is a companion for the java-strictexception.xml/DoNotExtendJavaLangError, detecting direct extensions of java.lang.Throwable.

  • The new Java rule ForLoopCanBeForeach (category errorprone) helps to identify those for-loops that can be safely refactored into for-each-loops available since java 1.5.

  • The new Java rule AvoidFileStream (category performance) helps to identify code relying on FileInputStream / FileOutputStream which, by using a finalizer, produces extra / unnecessary overhead to garbage collection, and should be replaced with Files.newInputStream / Files.newOutputStream available since java 1.7.

  • The new Java rule DataClass (category design) detects simple data-holders without behaviour. This might indicate that the behaviour is scattered elsewhere and the data class exposes the internal data structure, which breaks encapsulation.

  • The new Apex rule AvoidDirectAccessTriggerMap (category errorprone) helps to identify direct array access to triggers, which can produce bugs by either accessing non-existing indexes, or leaving them out. You should use for-each-loops instead.

  • The new Apex rule AvoidHardcodingId (category errorprone) detects hardcoded strings that look like identifiers and flags them. Record IDs change between environments, meaning hardcoded ids are bound to fail under a different setup.

  • The new Apex rule CyclomaticComplexity (category design) detects overly complex classes and methods. The report threshold can be configured separately for classes and methods.

  • A whole bunch of new rules has been added to Apex. They all fit into the category errorprone. The 5 rules are migrated for Apex from the equivalent Java rules and include:
    • EmptyCatchBlock to detect catch blocks completely ignoring exceptions.
    • EmptyIfStmt for if blocks with no content, that can be safely removed.
    • EmptyTryOrFinallyBlock for empty try / finally blocks that can be safely removed.
    • EmptyWhileStmt for empty while loops that can be safely removed.
    • EmptyStatementBlock for empty code blocks that can be safely removed.
  • The new Apex rule AvoidSoslInLoops (category performance) is the companion of the old AvoidSoqlInLoops rule, flagging SOSL (Salesforce Object Search Language) queries when within loops, to avoid governor issues, and hitting the database too often.

Modified Rules

  • The Java rule UnnecessaryFinalModifier (category codestyle, former ruleset java-unnecessarycode) has been merged into the rule UnnecessaryModifier. As part of this, the rule has been revamped to detect more cases. It will now flag anonymous class’ methods marked as final (can’t be overridden, so it’s pointless), along with final methods overridden / defined within enum instances. It will also flag final modifiers on try-with-resources.

  • The Java rule UnnecessaryParentheses (category codestyle, former ruleset java-controversial) has been merged into UselessParentheses (category codestyle, former ruleset java-unnecessary). The rule covers all scenarios previously covered by either rule.

  • The Java rule UncommentedEmptyConstructor (category documentation, former ruleset java-design) will now ignore empty constructors annotated with javax.inject.Inject.

  • The Java rule AbstractClassWithoutAnyMethod (category bestpractices, former ruleset java-design) will now ignore classes annotated with com.google.auto.value.AutoValue.

  • The Java rule GodClass (category design', former ruleset java-design`) has been revamped to use the new metrics framework.

  • The Java rule LooseCoupling (category bestpractices, former ruleset java-coupling) has been replaced by the typeresolution-based implementation.

  • The Java rule CloneMethodMustImplementCloneable (category errorprone, former ruleset java-clone) has been replaced by the typeresolution-based implementation and is now able to detect cases if a class implements or extends a Cloneable class/interface.

  • The Java rule UnusedImports (category bestpractices, former ruleset java-imports) has been replaced by the typeresolution-based implementation and is now able to detect unused on-demand imports.

  • The Java rule SignatureDeclareThrowsException (category design, former ruleset ‘java-strictexception’) has been replaced by the typeresolution-based implementation. It has a new property IgnoreJUnitCompletely, which allows all methods in a JUnit testcase to throw exceptions.

  • The Java rule NPathComplexity (category design, former ruleset java-codesize) has been revamped to use the new metrics framework. Its report threshold can be configured via the property reportLevel, which replaces the now deprecated property minimum.

  • The Java rule CyclomaticComplexity (category design, former ruleset java-codesize) has been revamped to use the new metrics framework. Its report threshold can be configured via the properties classReportLevel and methodReportLevel separately. The old property reportLevel, which configured the level for both total class and method complexity, is deprecated.

  • The Java rule CommentRequired (category documentation, former ruleset java-comments) has been revamped to include 2 new properties:
    • accessorCommentRequirement to specify documentation requirements for getters and setters (default to ignored)
    • methodWithOverrideCommentRequirement to specify documentation requirements for methods annotated with @Override (default to ignored)
  • The Java rule EmptyCatchBlock (category errorprone, former ruleset java-empty) has been changed to ignore exceptions named ignore or expected by default. You can still override this behaviour by setting the allowExceptionNameRegex property.

  • The Java rule OptimizableToArrayCall (category performance, former ruleset design) has been modified to fit for the current JVM implementations: It basically detects now the opposite and suggests to use Collection.toArray(new E[0]) with a zero-sized array. See Arrays of Wisdom of the Ancients.

Deprecated Rules

  • The Java rules NcssConstructorCount, NcssMethodCount, and NcssTypeCount (ruleset java-codesize) have been deprecated. They will be replaced by the new rule NcssCount in the category design.

  • The Java rule LooseCoupling in ruleset java-typeresolution is deprecated. Use the rule with the same name from category bestpractices instead.

  • The Java rule CloneMethodMustImplementCloneable in ruleset java-typeresolution is deprecated. Use the rule with the same name from category errorprone instead.

  • The Java rule UnusedImports in ruleset java-typeresolution is deprecated. Use the rule with the same name from category bestpractices instead.

  • The Java rule SignatureDeclareThrowsException in ruleset java-typeresolution is deprecated. Use the rule with the same name from category design instead.

  • The Java rule EmptyStaticInitializer in ruleset java-empty is deprecated. Use the rule EmptyInitializer from the category errorprone, which covers both static and non-static empty initializers.`

  • The Java rules GuardDebugLogging (ruleset java-logging-jakarta-commons) and GuardLogStatementJavaUtil (ruleset java-logging-java) have been deprecated. Use the rule GuardLogStatement from the category bestpractices, which covers all cases regardless of the logging framework.

Removed Rules

  • The deprecated Java rule UseSingleton has been removed from the ruleset java-design. The rule has been renamed long time ago to UseUtilityClass (category design).

Java Symbol Table

A bug in symbol table prevented the symbol table analysis to properly match primitive arrays types. The issue affected the java-unsedcode/UnusedPrivateMethod rule, but other rules may now produce improved results as consequence of this fix.

Apex Parser Update

The Apex parser version was bumped, from 1.0-sfdc-187 to 210-SNAPSHOT. This update let us take full advantage of the latest improvements from Salesforce, but introduces some breaking changes:

  • BlockStatements are now created for all control structures, even if no brace is used. We have therefore added a hasCurlyBrace method to differentiate between both scenarios.
  • New AST node types are available. In particular CastExpression, ConstructorPreamble, IllegalStoreExpression, MethodBlockStatement, Modifier, MultiStatement, NestedExpression, NestedStoreExpression, NewKeyValueObjectExpression and StatementExecuted
  • Some nodes have been removed. Such is the case of TestNode, DottedExpression and NewNameValueObjectExpression (replaced by NewKeyValueObjectExpression)

All existing rules have been updated to reflect these changes. If you have custom rules, be sure to update them.

For more info about the included Apex parser, see the new pmd module “pmd-apex-jorje”, which packages and provides the parser as a binary.

Incremental Analysis

The incremental analysis feature first introduced in PMD 5.6.0 has been enhanced. A few minor issues have been fixed, and several improvements have been performed to make it more accurate.

The cache will now detect changes to the JARs referenced in the auxclasspath instead of simply looking at their paths and order. This means that if you are referencing a JAR you are overwriting in some way, the incremental analysis can now detect it and invalidate it’s cache to avoid false reports.

Similarly, any changes to the execution classpath of PMD will invalidate the cache. This means that if you have custom rules packaged in a jar, any changes to it will invalidate the cache automatically.

We have also improved logging on the analysis code, allowing better insight into how the cache is performing, under debug / verbose builds you can even see individual hits / misses to the cache (and the reason for any miss!)

Finally, as this feature keeps maturing, we are gently pushing this forward. If not using incremental analysis, a warning will now be produced suggesting users to adopt it for better performance.

Rule and Report Properties

The implementation around the properties support for rule properties and report properties has been revamped to be fully typesafe. Along with that change, the support classes have been moved into an own package net.sourceforge.pmd.properties. While there is no change necessary in the ruleset XML files, when using/setting values for rules, there are adjustments necessary when declaring properties in Java-implemented rules.

Rule properties can be declared both for Java based rules and XPath rules. This is now very well documented in Working with properties.

With PMD 6.0.0, multivalued properties are now also possible with XPath rules.

Fixed Issues

  • all
    • #394: [core] PMD exclude rules are failing with IllegalArgumentException with non-default minimumPriority
    • #532: [core] security concerns on URL-based rulesets
    • #538: [core] Provide an XML Schema for XML reports
    • #600: [core] Nullpointer while creating cache File
    • #604: [core] Incremental analysis should detect changes to jars in classpath
    • #608: [core] Add DEBUG log when applying incremental analysis
    • #618: [core] Incremental Analysis doesn’t close file correctly on Windows upon a cache hit
    • #643: [core] PMD Properties (dev-properties) breaks markup on CodeClimateRenderer
    • #680: [core] Isolate classloaders for runtime and auxclasspath
    • #762: [core] Remove method and file property from available property descriptors for XPath rules
    • #763: [core] Turn property descriptor util into an enum and enrich its interface
  • apex
    • #265: [apex] Make Rule suppression work
    • #488: [apex] Use Apex lexer for CPD
    • #489: [apex] Update Apex compiler
    • #500: [apex] Running through CLI shows jorje optimization messages
    • #605: [apex] java.lang.NoClassDefFoundError in the latest build
    • #637: [apex] Avoid SOSL in loops
    • #760: [apex] EmptyStatementBlock complains about missing rather than empty block
    • #766: [apex] Replace old Jorje parser with new one
    • #768: [apex] java.lang.NullPointerException from PMD
  • cpp
    • #448: [cpp] Write custom CharStream to handle continuation characters
  • java
    • #1454: [java] OptimizableToArrayCall is outdated and invalid in current JVMs
    • #1513: [java] Remove deprecated rule UseSingleton
    • #328: [java] java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/servlet/jsp/PageContext
    • #487: [java] Fix typeresolution for anonymous extending object
    • #496: [java] processing error on generics inherited from enclosing class
    • #510: [java] Typeresolution fails on a simple primary when the source is loaded from a class literal
    • #527: [java] Lombok getter annotation on enum is not recognized correctly
    • #534: [java] NPE in MethodTypeResolution for static methods
    • #603: [core] incremental analysis should invalidate upon Java rule plugin changes
    • #650: [java] ProcesingError analyzing code under 5.8.1
    • #732: [java] LinkageError with aux classpath
  • java-basic
    • #565: [java] False negative on DontCallThreadRun when extending Thread
  • java-comments
    • #396: [java] CommentRequired: add properties to ignore @Override method and getters / setters
    • #536: [java] CommentDefaultAccessModifierRule ignores constructors
  • java-controversial
    • #388: [java] controversial.AvoidLiteralsInIfCondition 0.0 false positive
    • #408: [java] DFA not analyzing asserts
    • #537: [java] UnnecessaryParentheses fails to detect obvious scenario
  • java-design
    • #357: [java] UncommentedEmptyConstructor consider annotations on Constructor
    • #438: [java] Relax AbstractClassWithoutAnyMethod when class is annotated by @AutoValue
    • #590: [java] False positive on MissingStaticMethodInNonInstantiatableClass
  • java-logging * #457: [java] Merge all log guarding rules * #721: [java] NPE in PMD 5.8.1 InvalidSlf4jMessageFormat
  • java-sunsecure
    • #468: [java] ArrayIsStoredDirectly false positive
  • java-unusedcode
    • #521: [java] UnusedPrivateMethod returns false positives with primitive data type in map argument
  • java-unnecessarycode
    • #412: [java] java-unnecessarycode/UnnecessaryFinalModifier missing cases
    • #676: [java] java-unnecessarycode/UnnecessaryFinalModifier on try-with-resources

API Changes

  • The class net.sourceforge.pmd.lang.dfa.NodeType has been converted to an enum. All node types are enum members now instead of int constants. The names for node types are retained.

  • The Properties API (rule and report properties) has been revamped to be fully typesafe. This is everything around net.sourceforge.pmd.properties.PropertyDescriptor.

    Note: All classes related to properties have been moved into the package net.sourceforge.pmd.properties.

  • The rule classes net.sourceforge.pmd.lang.apex.rule.apexunit.ApexUnitTestClassShouldHaveAsserts and net.sourceforge.pmd.lang.apex.rule.apexunit.ApexUnitTestShouldNotUseSeeAllDataTrue have been renamed to ApexUnitTestClassShouldHaveAssertsRule and ApexUnitTestShouldNotUseSeeAllDataTrueRule, respectively. This is to comply with the naming convention, that each rule class should be suffixed with “Rule”.

    This change has no impact on custom rulesets, since the rule names themselves didn’t change.

  • The never implemented method PMD.processFiles(PMDConfiguration, RuleSetFactory, Collection<File>, RuleContext, ProgressMonitor) along with the interface ProgressMonitor has been removed.

  • The method PMD.setupReport(RuleSets, RuleContext, String) is gone. It was used to report dysfunctional rules. But PMD does this now automatically before processing the files, so there is no need for this method anymore.

  • All APIs deprecated in older versions are now removed. This includes:
    • Renderer.getPropertyDefinitions
    • AbstractRenderer.defineProperty(String, String)
    • AbstractRenderer.propertyDefinitions
    • ReportListener
    • Report.addListener(ReportListener)
    • SynchronizedReportListener
    • CPDConfiguration.CPDConfiguration(int, Language, String)
    • CPDConfiguration.getRendererFromString(String)
    • StreamUtil
    • StringUtil.appendXmlEscaped(StringBuilder, String)
    • StringUtil.htmlEncode(String)
  • Several methods in net.sourceforge.pmd.util.CollectionUtil have been deprecated and will be removed in PMD 7.0.0. In particular:
    • CollectionUtil.addWithoutDuplicates(T[], T)
    • CollectionUtil.addWithoutDuplicates(T[], T[])
    • CollectionUtil.areSemanticEquals(T[], T[])
    • CollectionUtil.areEqual(Object, Object)
    • CollectionUtil.arraysAreEqual(Object, Object)
    • CollectionUtil.valuesAreTransitivelyEqual(Object[], Object[])
  • Several methods in net.sourceforge.pmd.util.StringUtil have been deprecated and will be removed in PMD 7.0.0. In particular:
    • StringUtil.startsWithAny(String, String[])
    • StringUtil.isNotEmpty(String)
    • StringUtil.isEmpty(String)
    • StringUtil.isMissing(String)
    • StringUtil.areSemanticEquals(String, String)
    • StringUtil.replaceString(String, String, String)
    • StringUtil.replaceString(String, char, String)
    • StringUtil.substringsOf(String, char)
    • StringUtil.substringsOf(String, String)
    • StringUtil.asStringOn(StringBuffer, Iterator, String)
    • StringUtil.asStringOn(StringBuilder, Object[], String)
    • StringUtil.lpad(String, int)
  • The class net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition is now abstract, and has been enhanced to provide several new methods.

  • The constructor of net.sourceforge.pmd.RuleSetFactory, which took a ClassLoader is deprecated. Please use the alternative constructor with the net.sourceforge.pmd.util.ResourceLoader instead.

  • The following GUI related classes have been deprecated and will be removed in PMD 7.0.0. The tool “bgastviewer”, that could be started via the script bgastviewer.bat or run.sh bgastviewer is deprecated, too, and will be removed in PMD 7.0.0. Both the “old designer” and “bgastviewer” are replaced by the New Rule Designer.
    • net.sourceforge.pmd.util.designer.CodeEditorTextPane
    • net.sourceforge.pmd.util.designer.CreateXMLRulePanel
    • net.sourceforge.pmd.util.designer.Designer
    • net.sourceforge.pmd.util.designer.DFAPanel
    • net.sourceforge.pmd.util.designer.LineGetter
    • net.sourceforge.pmd.util.viewer.Viewer
    • net.sourceforge.pmd.util.viewer.gui.ActionCommands
    • net.sourceforge.pmd.util.viewer.gui.ASTPanel
    • net.sourceforge.pmd.util.viewer.gui.EvaluationResultsPanel
    • net.sourceforge.pmd.util.viewer.gui.MainFrame
    • net.sourceforge.pmd.util.viewer.gui.ParseExceptionHandler
    • net.sourceforge.pmd.util.viewer.gui.SourceCodePanel
    • net.sourceforge.pmd.util.viewer.gui.XPathPanel
    • net.sourceforge.pmd.util.viewer.gui.menu.ASTNodePopupMenu
    • net.sourceforge.pmd.util.viewer.gui.menu.AttributesSubMenu
    • net.sourceforge.pmd.util.viewer.gui.menu.SimpleNodeSubMenu
    • net.sourceforge.pmd.util.viewer.gui.menu.XPathFragmentAddingItem
    • net.sourceforge.pmd.util.viewer.model.ASTModel
    • net.sourceforge.pmd.util.viewer.model.AttributeToolkit
    • net.sourceforge.pmd.util.viewer.model.SimpleNodeTreeNodeAdapter
    • net.sourceforge.pmd.util.viewer.model.ViewerModel
    • net.sourceforge.pmd.util.viewer.model.ViewerModelEvent
    • net.sourceforge.pmd.util.viewer.model.ViewerModelListener
    • net.sourceforge.pmd.util.viewer.util.NLS
  • The following methods in net.sourceforge.pmd.Rule have been deprecated and will be removed in PMD 7.0.0. All methods are replaced by their bean-like counterparts
    • void setUsesDFA(). Use void setDfa(boolean) instead.
    • boolean usesDFA(). Use boolean isDfa() instead.
    • void setUsesTypeResolution(). Use void setTypeResolution(boolean) instead.
    • boole