pmd / pmd

An extensible multilanguage static code analyzer.

Home Page:https://pmd.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[java] UnusedPrivateMethod false-positive / method reference in combination with custom object

kesslerj opened this issue · comments

Affects PMD Version: 7.1.0

Rule: UnusedPrivateMethod

Description:

The private static method int foo(String s) is incorrectly recognized as an unused private method. The rule applies in the upper block of the code snippet, but not in the lower block - as method int foo2(String s) is not detected as false positive..

It is difficult for me to give a comprehensible explanation (which is also reflected in the title of the issue 😅), but it looks as if the rule applies incorrectly if the method is called via method reference and a custom object is used in the structure of the stream.

Code Sample demonstrating the issue:

Full code example can be found here: https://github.com/kesslerj/pmd-unused-private-method-issue-example-project .

public class Main {

  public static void main(String[] args) {
    System.out.println("list");

    // usage of method reference in combination with a custom object leads to a false positive of PMD.UnusedPrivateMethod
    List.of(new StringWrapper().getString())
        .stream()

        .map(Main::foo)
        .filter(Objects::nonNull)
        .toList();

    // no false positive .. :/
    List.of("s")
        .stream()
        .map(Main::foo2)
        .filter(Objects::nonNull)
        .toList();
  }

  private static int foo(String s) {
    return s.length();
  }

  private static int foo2(String s) {
    return s.length();
  }

}
public class StringWrapper {

  public String getString(){
    return "s";
  }
}

Expected outcome:

PMD reports a violation at line 27, but that's wrong. That's a false positive.

[INFO] PMD Failure: de.jk.examples.pmd.demo.Main:27 Rule:UnusedPrivateMethod Priority:3 Avoid unused private methods such as 'foo(String)'..

Running PMD through: Maven

Hi and thanks for putting together a MWE. The reason this only occurs when you use a custom object is that PMD does not have access to compiled class information for this type. This is due to a mistake in the way PMD is configured, namely, you should run the compiler before PMD is run in Maven. You should change the phase of execution of PMD to verify to make sure the compiler runs before PMD: https://github.com/kesslerj/pmd-unused-private-method-issue-example-project/blob/main/pom.xml#L43

That being said, looking into this allowed me to improve a bit the logic we use to handle unresolved types. Even without configuring PMD properly, we should not complain anymore once #4989 is merged

I remember that we once moved it to the validate phase so that it would be executed together with Checkstyle right at the beginning. But that doesn't seem to be a technically clean solution.

@oowekyala Thanks for pointing me out.