Skip to content

[java] AccessorMethodGeneration false positives with compile time constants #808

@TWiStErRob

Description

@TWiStErRob

Affects PMD Version: 5.8.1, 6.0.0 (and probably 5.5.4 upwards since the rule was introduced)

Rule: AccessorMethodGeneration

Description: constants are inlined at compile time, so no method is generated to access them.
Valid violations confirmed via javac Outer.java && javap Outer.class which shows the access$ methods.

Code Sample demonstrating the issue:

@SuppressWarnings("unused")
class Outer {
  private static final String CONST_STRING = "value";
  private static final String CALCULATED_STRING = "value" + 0;
  private static final int LITERAL = 0;
  private static final int CALCULATED = LITERAL * 2;
  private static final int REFERENCED = Thread.MIN_PRIORITY;
  private static final int CAST = (int) 0L;
  private static final long NON_CONSTANT = java.util.concurrent.TimeUnit.SECONDS.toMillis(10);
  private static final int LATE_INIT;
  static {
  	LATE_INIT = 0;
  }

  class Inner {
    @Override
    public String toString() {
      return "" // separate lines so the rule violations show up better
           + CONST_STRING
           + CALCULATED_STRING
           + LITERAL
           + CALCULATED
           + LATE_INIT    // valid violation
           + REFERENCED
           + CAST
           + NON_CONSTANT // valid violation
      ;
    }
  }
}

Running PMD through: Gradle (5.8.1) and CLI (6.0.0 pmd -d . -format text -R java-design)

Workaround

I was able to suppress the most basic false positives (CONST_STRING and LITERAL) via:

<rule ref="rulesets/java/design.xml/AccessorMethodGeneration">
        <properties>
            <!-- Ignore references to `private static final * * = <literal>`
                 Suppress via XPath: current node (access that generates the accessor) is .
                 Check if there exists a FieldDeclaration (private static final)
                 which has a VariableInitializer with a Literal
                 and the name (@Image) of the declaration is the same as the accessed member.
                 TODO calculated constant values still show up as false positive
            -->
            <property name="violationSuppressXPath" value="
            .[@Image =
                //FieldDeclaration[@Private = 'true' and @Static='true' and @Final='true']
                /VariableDeclarator[
                    VariableInitializer/Expression/PrimaryExpression[not(PrimarySuffix)]/PrimaryPrefix/Literal
                ]/VariableDeclaratorId/@Image
             ]" />
        </properties>
    </rule>

Metadata

Metadata

Assignees

No one assigned

    Labels

    a:false-positivePMD flags a piece of code that is not problematic

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions