Skip to content

[java] Deadlock when executing PMD in multiple threads #5293

@AB-xdev

Description

@AB-xdev

Affects PMD Version:

7.7.0, 7.6.0
probably all releases in recent time

Description:

We are executing the following on a multi-Maven project:
mvn -B test pmd:check -P pmd -DskipTests

Which causes a deadlock on some machines:
MvnPMDDeadlock

The problem is likely caused by some unfortunate CPU situation that only occurs on certain machines with certain code and is therefore extremely difficult to reproduce.

Summary from the initial maven issue

michael-o
Does a downgrade help?

AB-xdev
@ michael-o
I'm currently checking the exact cause as we got a ton of Maven plugin updates over the weekend.
Maybe also one of those broke it...

AB-xdev
Okay my conclusions so far: This is probably not related to the PMD version

I downgraded to a state before the update and the same error also occurs randomly.
I was unable to reproduce or find the problem ín any of our ~50 CIs so this must be caused either by

  • Windows
  • hardware configuration
  • anti-virus solution

However as of now I think this is a hardware configuration based problem:

  • The problem also occurred with disabled anti-virus
  • I checked with a colleague which has nearly the same hardware as I but a different Windows version (10/11) and it also happened on his machine:
    screenshot-1
    Doing some further testing with thread configurations now...

AB-xdev
I was able to reproduce the problem with different maven parallelization/thread configurations (-T8, -T1, ...) on the same machine but not on others.
The amount of spawned PMD threads does NOT depend on the selected maven parallelization and is ALWAYS the same amount as CPU threads (Runtime.getRuntime().availableProcessors()).
It's likely some unfortunate CPU situation that only occurs on certain machines with certain code.

I inspected another Threaddump further and as far as i can tell the problem is a legitimate PMD problem.
It looks like multiple threads are started for analysis, which process different classes/pieces of code and walk through related code.
While they are being processed the threads (sometimes) lock each other, resulting in a deadlock:

Example from the Threaddump:

Thread #1: Class A (locked) -> ... -> Class C (waits for lock from Thread #16)
Thread #16: Class C (locked) -> Class A (waits for lock from Thread #1)
→ Deadlock

(for more details see the deadlock section at the end of the attached Thread dump)

The key finding from the Maven-Plugin issue is:

I inspected another Threaddump further and as far as i can tell the problem is a legitimate PMD problem.
It looks like multiple threads are started for analysis, which process different classes/pieces of code and walk through related code.
While they are being processed the threads (sometimes) lock each other, resulting in a deadlock:

Example from the Threaddump:

Thread #1: Class A (locked) -> ... -> Class C (waits for lock from Thread #16)
Thread #16: Class C (locked) -> Class A (waits for lock from Thread #1)
→ Deadlock

Exception Stacktrace:

Deadlock in Threaddump
Found one Java-level deadlock:
=============================
"PmdThread 1":
  waiting to lock monitor 0x0000025c81905b70 (object 0x000000041088f710, a net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase$1),
  which is held by "PmdThread 16"

"PmdThread 16":
  waiting to lock monitor 0x0000025c8024f840 (object 0x0000000410800000, a net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase$1),
  which is held by "PmdThread 1"

Java stack information for the threads listed above:
===================================================
"PmdThread 1":
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.ParseLock.getFinalStatus(ParseLock.java:28)
        - waiting to lock <0x000000041088f710> (a net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase$1)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.ParseLock.ensureParsed(ParseLock.java:22)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase.ensureParsed(GenericSigBase.java:76)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase.getTypeParams(GenericSigBase.java:92)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.ClassStub.getTypeParameters(ClassStub.java:314)
        at net.sourceforge.pmd.lang.java.symbols.JTypeParameterOwnerSymbol.getTypeParameterCount(JTypeParameterOwnerSymbol.java:47)
        at net.sourceforge.pmd.lang.java.types.ClassTypeImpl.typeArgsAreOk(ClassTypeImpl.java:446)
        at net.sourceforge.pmd.lang.java.types.ClassTypeImpl.validateParams(ClassTypeImpl.java:420)
        at net.sourceforge.pmd.lang.java.types.ClassTypeImpl.<init>(ClassTypeImpl.java:69)
        at net.sourceforge.pmd.lang.java.types.ClassTypeImpl.<init>(ClassTypeImpl.java:64)
        at net.sourceforge.pmd.lang.java.types.TypeSystem.parameterise(TypeSystem.java:530)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.TypeSigParser$TypeScanner.makeClassType(TypeSigParser.java:364)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.TypeSigParser.classType(TypeSigParser.java:164)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.TypeSigParser.typeSignature(TypeSigParser.java:148)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.TypeSigParser.typeSignature(TypeSigParser.java:124)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.TypeSigParser.typeArg(TypeSigParser.java:209)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.TypeSigParser.typeArgsOpt(TypeSigParser.java:184)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.TypeSigParser.classType(TypeSigParser.java:162)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.TypeSigParser.classHeader(TypeSigParser.java:33)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.SignatureParser$$Lambda/0x0000025c38548448.parse(Unknown Source)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.SignatureParser.parseFully(SignatureParser.java:100)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.SignatureParser.parseClassSignature(SignatureParser.java:57)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase$LazyClassSignature.doParse(GenericSigBase.java:155)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase$1.doParse(GenericSigBase.java:54)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.ParseLock.getFinalStatus(ParseLock.java:33)
        - locked <0x000000041088f8a0> (a net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase$1)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.ParseLock.ensureParsed(ParseLock.java:22)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase.ensureParsed(GenericSigBase.java:76)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase.getTypeParams(GenericSigBase.java:92)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.ClassStub.getTypeParameters(ClassStub.java:314)
        at net.sourceforge.pmd.lang.java.symbols.JTypeParameterOwnerSymbol.getTypeParameterCount(JTypeParameterOwnerSymbol.java:47)
        at net.sourceforge.pmd.lang.java.types.ClassTypeImpl.typeArgsAreOk(ClassTypeImpl.java:446)
        at net.sourceforge.pmd.lang.java.types.ClassTypeImpl.validateParams(ClassTypeImpl.java:420)
        at net.sourceforge.pmd.lang.java.types.ClassTypeImpl.<init>(ClassTypeImpl.java:69)
        at net.sourceforge.pmd.lang.java.types.ClassTypeImpl.<init>(ClassTypeImpl.java:64)
        at net.sourceforge.pmd.lang.java.types.TypeSystem.parameterise(TypeSystem.java:530)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.TypeSigParser$TypeScanner.makeClassType(TypeSigParser.java:364)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.TypeSigParser.classType(TypeSigParser.java:164)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.TypeSigParser.typeSignature(TypeSigParser.java:148)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.TypeSigParser.typeSignature(TypeSigParser.java:124)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.TypeSigParser.typeArg(TypeSigParser.java:209)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.TypeSigParser.typeArgsOpt(TypeSigParser.java:184)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.TypeSigParser.classType(TypeSigParser.java:162)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.TypeSigParser.classHeader(TypeSigParser.java:39)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.SignatureParser$$Lambda/0x0000025c38548448.parse(Unknown Source)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.SignatureParser.parseFully(SignatureParser.java:100)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.SignatureParser.parseClassSignature(SignatureParser.java:57)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase$LazyClassSignature.doParse(GenericSigBase.java:155)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase$1.doParse(GenericSigBase.java:54)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.ParseLock.getFinalStatus(ParseLock.java:33)
        - locked <0x0000000410800000> (a net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase$1)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.ParseLock.ensureParsed(ParseLock.java:22)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase.ensureParsed(GenericSigBase.java:76)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase.getTypeParams(GenericSigBase.java:92)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.ClassStub.getTypeParameters(ClassStub.java:314)
        at net.sourceforge.pmd.lang.java.symbols.JTypeParameterOwnerSymbol.getTypeParameterCount(JTypeParameterOwnerSymbol.java:47)
        at net.sourceforge.pmd.lang.java.ast.AstDisambiguationPass$DisambigVisitor.postProcess(AstDisambiguationPass.java:219)
        at net.sourceforge.pmd.lang.java.ast.AstDisambiguationPass$DisambigVisitor.visit(AstDisambiguationPass.java:189)
        at net.sourceforge.pmd.lang.java.ast.AstDisambiguationPass$DisambigVisitor.visit(AstDisambiguationPass.java:80)
        at net.sourceforge.pmd.lang.java.ast.ASTClassType.acceptVisitor(ASTClassType.java:157)
        at net.sourceforge.pmd.lang.java.ast.AbstractJavaNode.acceptVisitor(AbstractJavaNode.java:38)
        at net.sourceforge.pmd.lang.java.ast.AstDisambiguationPass.lambda$disambigWithCtx$0(AstDisambiguationPass.java:58)
        at net.sourceforge.pmd.lang.java.ast.AstDisambiguationPass$$Lambda/0x0000025c38546508.accept(Unknown Source)
        at java.util.Iterator.forEachRemaining(java.base@21.0.5/Iterator.java:133)
        at net.sourceforge.pmd.lang.ast.internal.IteratorBasedNStream.forEach(IteratorBasedNStream.java:102)
        at net.sourceforge.pmd.lang.java.ast.AstDisambiguationPass.disambigWithCtx(AstDisambiguationPass.java:58)
        at net.sourceforge.pmd.lang.java.ast.InternalApiBridge.disambigWithCtx(InternalApiBridge.java:77)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymTableFactory.disambig(SymTableFactory.java:103)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymbolTableResolver$MyVisitor.visitTypeDecl(SymbolTableResolver.java:293)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymbolTableResolver$MyVisitor.visitTypeDecl(SymbolTableResolver.java:138)
        at net.sourceforge.pmd.lang.java.ast.JavaVisitorBase.visit(JavaVisitorBase.java:57)
        at net.sourceforge.pmd.lang.java.ast.ASTClassDeclaration.acceptVisitor(ASTClassDeclaration.java:38)
        at net.sourceforge.pmd.lang.java.ast.AbstractJavaNode.acceptVisitor(AbstractJavaNode.java:38)
        at net.sourceforge.pmd.lang.ast.AstVisitorBase.visitChildren(AstVisitorBase.java:31)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymbolTableResolver$MyVisitor.visit(SymbolTableResolver.java:247)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymbolTableResolver$MyVisitor.visit(SymbolTableResolver.java:138)
        at net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit.acceptVisitor(ASTCompilationUnit.java:109)
        at net.sourceforge.pmd.lang.java.ast.AbstractJavaNode.acceptVisitor(AbstractJavaNode.java:38)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymbolTableResolver$MyVisitor.traverse(SymbolTableResolver.java:164)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymbolTableResolver.traverse(SymbolTableResolver.java:101)
        at net.sourceforge.pmd.lang.java.internal.JavaAstProcessor.lambda$process$1(JavaAstProcessor.java:132)
        at net.sourceforge.pmd.lang.java.internal.JavaAstProcessor$$Lambda/0x0000025c38534cc0.run(Unknown Source)
        at net.sourceforge.pmd.benchmark.TimeTracker.bench(TimeTracker.java:163)
        at net.sourceforge.pmd.lang.java.internal.JavaAstProcessor.process(JavaAstProcessor.java:132)
        at net.sourceforge.pmd.lang.java.internal.JavaAstProcessor.process(JavaAstProcessor.java:166)
        at net.sourceforge.pmd.lang.java.internal.JavaAstProcessor.process(JavaAstProcessor.java:150)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.parseImpl(JavaParser.java:69)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.parseImpl(JavaParser.java:25)
        at net.sourceforge.pmd.lang.ast.impl.javacc.JjtreeParserAdapter.parse(JjtreeParserAdapter.java:36)
        at net.sourceforge.pmd.lang.impl.PmdRunnable.parse(PmdRunnable.java:112)
        at net.sourceforge.pmd.lang.impl.PmdRunnable.processSource(PmdRunnable.java:132)
        at net.sourceforge.pmd.lang.impl.PmdRunnable.run(PmdRunnable.java:80)
        at java.util.concurrent.Executors$RunnableAdapter.call(java.base@21.0.5/Executors.java:572)
        at java.util.concurrent.FutureTask.run(java.base@21.0.5/FutureTask.java:317)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.5/ThreadPoolExecutor.java:1144)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.5/ThreadPoolExecutor.java:642)
        at java.lang.Thread.runWith(java.base@21.0.5/Thread.java:1596)
        at java.lang.Thread.run(java.base@21.0.5/Thread.java:1583)
"PmdThread 16":
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.ParseLock.getFinalStatus(ParseLock.java:28)
        - waiting to lock <0x0000000410800000> (a net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase$1)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.ParseLock.ensureParsed(ParseLock.java:22)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase.ensureParsed(GenericSigBase.java:76)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase.getTypeParams(GenericSigBase.java:92)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.ClassStub.getTypeParameters(ClassStub.java:314)
        at net.sourceforge.pmd.lang.java.symbols.JTypeParameterOwnerSymbol.getLexicalScope(JTypeParameterOwnerSymbol.java:42)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.ClassStub.getLexicalScope(ClassStub.java:326)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase.getEnclosingTypeParams(GenericSigBase.java:72)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.SignatureParser.typeParamsWrapper(SignatureParser.java:88)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.SignatureParser.parseClassSignature(SignatureParser.java:56)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase$LazyClassSignature.doParse(GenericSigBase.java:155)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase$1.doParse(GenericSigBase.java:54)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.ParseLock.getFinalStatus(ParseLock.java:33)
        - locked <0x000000041088f710> (a net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase$1)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.ParseLock.ensureParsed(ParseLock.java:22)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase.ensureParsed(GenericSigBase.java:76)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.GenericSigBase.getTypeParams(GenericSigBase.java:92)
        at net.sourceforge.pmd.lang.java.symbols.internal.asm.ClassStub.getTypeParameters(ClassStub.java:314)
        at net.sourceforge.pmd.lang.java.symbols.JTypeParameterOwnerSymbol.getTypeParameterCount(JTypeParameterOwnerSymbol.java:47)
        at net.sourceforge.pmd.lang.java.ast.AstDisambiguationPass$DisambigVisitor.postProcess(AstDisambiguationPass.java:219)
        at net.sourceforge.pmd.lang.java.ast.AstDisambiguationPass$DisambigVisitor.visit(AstDisambiguationPass.java:164)
        at net.sourceforge.pmd.lang.java.ast.AstDisambiguationPass$DisambigVisitor.visit(AstDisambiguationPass.java:80)
        at net.sourceforge.pmd.lang.java.ast.ASTClassType.acceptVisitor(ASTClassType.java:157)
        at net.sourceforge.pmd.lang.java.ast.AbstractJavaNode.acceptVisitor(AbstractJavaNode.java:38)
        at net.sourceforge.pmd.lang.java.ast.AstDisambiguationPass.lambda$disambigWithCtx$0(AstDisambiguationPass.java:58)
        at net.sourceforge.pmd.lang.java.ast.AstDisambiguationPass$$Lambda/0x0000025c38546508.accept(Unknown Source)
        at net.sourceforge.pmd.lang.ast.internal.SingletonNodeStream.forEach(SingletonNodeStream.java:87)
        at net.sourceforge.pmd.lang.java.ast.AstDisambiguationPass.disambigWithCtx(AstDisambiguationPass.java:58)
        at net.sourceforge.pmd.lang.java.ast.InternalApiBridge.disambigWithCtx(InternalApiBridge.java:77)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymTableFactory.disambig(SymTableFactory.java:103)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymbolTableResolver$MyVisitor.visit(SymbolTableResolver.java:188)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymbolTableResolver$MyVisitor.visit(SymbolTableResolver.java:138)
        at net.sourceforge.pmd.lang.java.ast.ASTClassType.acceptVisitor(ASTClassType.java:157)
        at net.sourceforge.pmd.lang.java.ast.AbstractJavaNode.acceptVisitor(AbstractJavaNode.java:38)
        at net.sourceforge.pmd.lang.ast.AstVisitorBase.visitChildren(AstVisitorBase.java:31)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymbolTableResolver$MyVisitor.setTopSymbolTableAndVisitAllChildren(SymbolTableResolver.java:741)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymbolTableResolver$MyVisitor.visitMethodOrCtor(SymbolTableResolver.java:326)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymbolTableResolver$MyVisitor.visitMethodOrCtor(SymbolTableResolver.java:138)
        at net.sourceforge.pmd.lang.java.ast.JavaVisitorBase.visit(JavaVisitorBase.java:39)
        at net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration.acceptVisitor(ASTMethodDeclaration.java:59)
        at net.sourceforge.pmd.lang.java.ast.AbstractJavaNode.acceptVisitor(AbstractJavaNode.java:38)
        at net.sourceforge.pmd.lang.ast.AstVisitorBase.visitChildren(AstVisitorBase.java:31)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymbolTableResolver$MyVisitor.visitTypeDecl(SymbolTableResolver.java:296)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymbolTableResolver$MyVisitor.visitTypeDecl(SymbolTableResolver.java:138)
        at net.sourceforge.pmd.lang.java.ast.JavaVisitorBase.visit(JavaVisitorBase.java:57)
        at net.sourceforge.pmd.lang.java.ast.ASTClassDeclaration.acceptVisitor(ASTClassDeclaration.java:38)
        at net.sourceforge.pmd.lang.java.ast.AbstractJavaNode.acceptVisitor(AbstractJavaNode.java:38)
        at net.sourceforge.pmd.lang.ast.AstVisitorBase.visitChildren(AstVisitorBase.java:31)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymbolTableResolver$MyVisitor.visit(SymbolTableResolver.java:247)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymbolTableResolver$MyVisitor.visit(SymbolTableResolver.java:138)
        at net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit.acceptVisitor(ASTCompilationUnit.java:109)
        at net.sourceforge.pmd.lang.java.ast.AbstractJavaNode.acceptVisitor(AbstractJavaNode.java:38)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymbolTableResolver$MyVisitor.traverse(SymbolTableResolver.java:164)
        at net.sourceforge.pmd.lang.java.symbols.table.internal.SymbolTableResolver.traverse(SymbolTableResolver.java:101)
        at net.sourceforge.pmd.lang.java.internal.JavaAstProcessor.lambda$process$1(JavaAstProcessor.java:132)
        at net.sourceforge.pmd.lang.java.internal.JavaAstProcessor$$Lambda/0x0000025c38534cc0.run(Unknown Source)
        at net.sourceforge.pmd.benchmark.TimeTracker.bench(TimeTracker.java:163)
        at net.sourceforge.pmd.lang.java.internal.JavaAstProcessor.process(JavaAstProcessor.java:132)
        at net.sourceforge.pmd.lang.java.internal.JavaAstProcessor.process(JavaAstProcessor.java:166)
        at net.sourceforge.pmd.lang.java.internal.JavaAstProcessor.process(JavaAstProcessor.java:150)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.parseImpl(JavaParser.java:69)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.parseImpl(JavaParser.java:25)
        at net.sourceforge.pmd.lang.ast.impl.javacc.JjtreeParserAdapter.parse(JjtreeParserAdapter.java:36)
        at net.sourceforge.pmd.lang.impl.PmdRunnable.parse(PmdRunnable.java:112)
        at net.sourceforge.pmd.lang.impl.PmdRunnable.processSource(PmdRunnable.java:132)
        at net.sourceforge.pmd.lang.impl.PmdRunnable.run(PmdRunnable.java:80)
        at java.util.concurrent.Executors$RunnableAdapter.call(java.base@21.0.5/Executors.java:572)
        at java.util.concurrent.FutureTask.run(java.base@21.0.5/FutureTask.java:317)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.5/ThreadPoolExecutor.java:1144)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.5/ThreadPoolExecutor.java:642)
        at java.lang.Thread.runWith(java.base@21.0.5/Thread.java:1596)
        at java.lang.Thread.run(java.base@21.0.5/Thread.java:1583)

Found 1 deadlock.

from Threaddump2.txt (recommended dump)

Here a a few thread-dumps:
Threaddump.txt
Threaddump_colleague.txt

Steps to reproduce:

Reproducing the bug is next to impossible, I could only do so on machines with similar hardware.
However here are a few steps that can be followed:

  1. Get a more complex maven project that uses PMD
  2. Run mvn -B test pmd:check -P pmd -DskipTests (maybe also with -T2C) with an insanely high CPU count: -XX:ActiveProcessorCount=64

Workaround

It's not possible to change the amount of spawned PMD threads from the Maven Plugin.
However one can manually lower that number to one thread by adding -XX:ActiveProcessorCount=1.
That way the check works reliable but it's really slow and it might also affect other parts of the build negatively.

Running PMD through: Maven

Java version: 21.0.5, vendor: Eclipse Adoptium
aka OpenJDK Runtime Environment Temurin-21.0.5+11 (build 21.0.5+11-LTS)
Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Windows 10 & 11
CPU: AMD Ryzen 3700X (8C/16T)
Private Multi Maven Project with around 15 modules and 30k LoC

Metadata

Metadata

Assignees

Labels

a:bugPMD crashes or fails to analyse a file.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions