Skip to content

[java] StackOverflowError with recursively bound type variable #5096

Closed
@slovdahl

Description

Affects PMD Version: 7.0.0, 7.1.0, 7.2.0, 7.3.0

Description:

I'm trying to upgrade PMD from 6.55.0 to 7.x but the PMD runs just end up in java.lang.StackoverflowErrrors.

ruleset.xml

<?xml version="1.0" encoding="UTF-8"?>
<ruleset name="PMD ruleset"
         xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">

  <description>PMD ruleset</description>

  <rule ref="category/java/bestpractices.xml/MissingOverride"/>
  <rule ref="category/java/bestpractices.xml/PrimitiveWrapperInstantiation"/>
  <rule ref="category/java/bestpractices.xml/ReplaceVectorWithList"/>
  <rule ref="category/java/bestpractices.xml/UseStandardCharsets"/>
  <rule ref="category/java/codestyle.xml/ExtendsObject"/>
  <rule ref="category/java/codestyle.xml/PackageCase"/>
  <rule ref="category/java/codestyle.xml/UnnecessaryCast"/>
  <rule ref="category/java/codestyle.xml/UnnecessarySemicolon"/>
</ruleset>

But also fails with just one of the rules in place.

Gradle configuration:

apply plugin: 'pmd'

pmd {
    toolVersion = '7.3.0'
    consoleOutput = true
    incrementalAnalysis = true
    ruleSets = [ "$rootProject.projectDir/gradle/pmd/ruleset.xml" ]
}

gradle.properties:

org.gradle.parallel=true
org.gradle.jvmargs=-Xmx3g

Tested with both Temurin 17 and 21 (the project requires at least 17) on Ubuntu 22.04.

Exception Stacktrace:

The topmost part of the stack trace inline, here is the full stack trace.

Caused by: java.lang.StackOverflowError
        at net.sourceforge.pmd.lang.java.types.Substitution.apply(Substitution.java:45)
        at net.sourceforge.pmd.lang.java.types.Substitution.apply(Substitution.java:28)
        at net.sourceforge.pmd.lang.java.types.SubstVar.subst(SubstVar.java:25)
        at net.sourceforge.pmd.lang.java.types.WildcardTypeImpl.subst(WildcardTypeImpl.java:35)
        at net.sourceforge.pmd.lang.java.types.WildcardTypeImpl.subst(WildcardTypeImpl.java:17)
        at net.sourceforge.pmd.lang.java.types.TypeOps.lambda$subst$0(TypeOps.java:950)
        at net.sourceforge.pmd.lang.java.types.TypeOps.mapPreservingSelf(TypeOps.java:977)
        at net.sourceforge.pmd.lang.java.types.TypeOps.subst(TypeOps.java:950)
        at net.sourceforge.pmd.lang.java.types.JClassType.subst(JClassType.java:78)
        at net.sourceforge.pmd.lang.java.types.JClassType.subst(JClassType.java:54)
        at net.sourceforge.pmd.lang.java.types.TypeOps.subst(TypeOps.java:941)
        at net.sourceforge.pmd.lang.java.types.TypeConversion.capture(TypeConversion.java:213)
        at net.sourceforge.pmd.lang.java.types.TypeConversion.capture(TypeConversion.java:154)
        at net.sourceforge.pmd.lang.java.types.TypeConversion.capture(TypeConversion.java:152)
        at net.sourceforge.pmd.lang.java.types.TypeOps$SubtypeVisitor.isConvertible(TypeOps.java:662)
        at net.sourceforge.pmd.lang.java.types.TypeOps$SubtypeVisitor.isConvertible(TypeOps.java:598)
        at net.sourceforge.pmd.lang.java.types.TypeOps.isConvertiblePure(TypeOps.java:415)
        at net.sourceforge.pmd.lang.java.types.TypeOps.mostSpecific(TypeOps.java:1757)
        at net.sourceforge.pmd.lang.java.types.Lub.glb(Lub.java:316)
        at net.sourceforge.pmd.lang.java.types.TypeSystem.glb(TypeSystem.java:723)
        at net.sourceforge.pmd.lang.java.types.TypeConversion.capture(TypeConversion.java:227)
        at net.sourceforge.pmd.lang.java.types.TypeConversion.capture(TypeConversion.java:154)
        at net.sourceforge.pmd.lang.java.types.TypeConversion.capture(TypeConversion.java:152)
        at net.sourceforge.pmd.lang.java.types.TypeOps$SubtypeVisitor.isConvertible(TypeOps.java:662)
        at net.sourceforge.pmd.lang.java.types.TypeOps$SubtypeVisitor.isConvertible(TypeOps.java:598)
        at net.sourceforge.pmd.lang.java.types.TypeOps.isConvertiblePure(TypeOps.java:415)
        at net.sourceforge.pmd.lang.java.types.TypeOps.mostSpecific(TypeOps.java:1757)
        at net.sourceforge.pmd.lang.java.types.Lub.glb(Lub.java:316)
        at net.sourceforge.pmd.lang.java.types.TypeSystem.glb(TypeSystem.java:723)
        at net.sourceforge.pmd.lang.java.types.TypeConversion.capture(TypeConversion.java:227)
        at net.sourceforge.pmd.lang.java.types.TypeConversion.capture(TypeConversion.java:154)
        at net.sourceforge.pmd.lang.java.types.TypeConversion.capture(TypeConversion.java:152)
        at net.sourceforge.pmd.lang.java.types.TypeOps$SubtypeVisitor.isConvertible(TypeOps.java:662)
        at net.sourceforge.pmd.lang.java.types.TypeOps$SubtypeVisitor.isConvertible(TypeOps.java:598)
        at net.sourceforge.pmd.lang.java.types.TypeOps.isConvertiblePure(TypeOps.java:415)
        at net.sourceforge.pmd.lang.java.types.TypeOps.mostSpecific(TypeOps.java:1757)
        at net.sourceforge.pmd.lang.java.types.Lub.glb(Lub.java:316)
        at net.sourceforge.pmd.lang.java.types.TypeSystem.glb(TypeSystem.java:723)

Code Sample demonstrating the issue:

I cannot share the project as is, and I haven't yet been able to figure out what exactly triggers it. Any help in pinpointing the problematic class would be appreciated.

Steps to reproduce:

TBD.

Running PMD through: Gradle 8.8

Metadata

Assignees

No one assigned

    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