PMD 6.4.0 released

29 May 2018

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:


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 has been deprecated. Use the newer TypeIsFunction in the same package.
  • The typeof methdos in have been deprecated. Use the newer typeIs method in the same class instead..
  • The methods isA, isEither and isNeither of Use the new isExactlyAny and isExactlyNone methods in the same class instead.

External Contributions