Skip to content

[java] New rule: OverridingThreadRun to prefer using Runnable#6555

Merged
adangel merged 3 commits into
pmd:mainfrom
zbynek:overriding-run
Apr 24, 2026
Merged

[java] New rule: OverridingThreadRun to prefer using Runnable#6555
adangel merged 3 commits into
pmd:mainfrom
zbynek:overriding-run

Conversation

@zbynek
Copy link
Copy Markdown
Contributor

@zbynek zbynek commented Mar 28, 2026

Describe the PR

The new rule suggests using Runnable instead of overriding Thread.run.

IntelliJ covers this by AnonymousHasLambdaAlternative

Related issues

Ready?

  • Added unit tests for fixed bug/feature
  • Passing all unit tests
  • Complete build ./mvnw clean verify passes (checked automatically by github actions)
  • Added (in-code) documentation (if needed)

@zbynek zbynek force-pushed the overriding-run branch 2 times, most recently from b370e48 to 77479d4 Compare March 28, 2026 11:18
@zbynek zbynek added the a:new-rule Proposal to add a new built-in rule label Mar 28, 2026
@pmd-actions-helper
Copy link
Copy Markdown
Contributor

pmd-actions-helper Bot commented Mar 28, 2026

Documentation Preview

Compared to main:
This changeset changes 0 violations,
introduces 0 new violations, 0 new errors and 0 new configuration errors,
removes 0 violations, 0 errors and 0 configuration errors.

Regression Tester Report

(comment created at 2026-03-29 10:58:53+00:00 for 1ed4ab7)

@adangel adangel changed the title [java] new rule OverridingThreadRun to prefer using Runnable [java] New rule: OverridingThreadRun to prefer using Runnable Apr 24, 2026
@adangel adangel added this to the 7.24.0 milestone Apr 24, 2026
Copy link
Copy Markdown
Member

@adangel adangel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

adangel added a commit that referenced this pull request Apr 24, 2026
@adangel adangel merged commit fe7fdbd into pmd:main Apr 24, 2026
13 checks passed
@zbynek
Copy link
Copy Markdown
Contributor Author

zbynek commented Apr 24, 2026

@adangel I noticed the regression report does not include this rule -- did I do something wrong here?

@adangel
Copy link
Copy Markdown
Member

adangel commented Apr 29, 2026

@adangel I noticed the regression report does not include this rule -- did I do something wrong here?

Good catch. If the rule doesn't appear in the regression report, this means, there are no instances of violations detected. We only list rules, where there is a violation. That's why there are no rules with 0 violations (either for base or patch).

The ruleset that is used for regression testing is simply this one: https://github.com/pmd/pmd/blob/main/.ci/files/all-regression-rules.xml - which contains java/multihreading.xml which contains OverridingThreadRun

I've tested this rule now separately - it seems to be working.

Now: With the help of IntelliJ I could identify a subclass of thread in java.base, that should have been found: https://github.com/openjdk/jdk/blob/da75f3c4ad5bdf25167a3ed80e51f567ab3dbd01/src/java.base/share/classes/java/lang/ref/Finalizer.java#L151
Note - we don't analyse the whole openjdk 11 source, but only subfolder java.base:

<src-subpath>src/java.base</src-subpath>

After tinkering a bit, I found the problem: The XPath expression is not correct - it uses count(//FormalParameter) - which searches for formal parameters in the whole compilation unit. So - as soon as there is a single method with one parameter somewhere in the same file, the rule won't find anything anymore.

The better XPath is:

//ClassDeclaration[ pmd-java:typeIs('java.lang.Thread') ]/ClassBody
    /MethodDeclaration[@Name="run"][FormalParameters/@Size=0]

@zbynek Can you please open a new PR to fix this? Then you should see violation in the report...

However, this doesn't find anonymous classes, e.g.

public class Foo {
    public static void main(String[] args) {
      new Thread() {
        public void run() {
          
        }
      }.start();
    }
}

Unfortunately, //AnonymousClassDeclaration[pmd-java:typeIs('java.lang.Thread')] doesn't find this anonymous thread - there is something missing in the type system in PMD. So, this fix wouldn't be straightforward.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a:new-rule Proposal to add a new built-in rule

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[java] New rule: Implement Runnable instead of extending Thread

2 participants