PMD fails with `Could not find {dependency}`

Hello!

Let me introduce my problem:

I have a simple mix project. I mean I have the project with the next structure:

root
|
\ A (spring-based with java)
\ B (It takes A)
\ C (It takes B)
...

So, each build.gradle looks like:

A module:

plugins {
    id 'java-library'
    id 'org.springframework.boot' version '3.4.4'
    id 'io.spring.dependency-management' version '1.1.7'
}

group = 'org.example'
version = '0.0.1-SNAPSHOT'

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
}

B module:

plugins {
    id 'java'
    id 'pmd'
}

pmd {
    consoleOutput = true
    toolVersion = "7.12.0"
}

group = 'org.example'
version = '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    implementation project(':A')
}

C module:

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.4.4'
    id 'io.spring.dependency-management' version '1.1.7'
}

group = 'org.example'
version = '0.0.1-SNAPSHOT'

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation project(':B')
}

tasks.named('test') {
    useJUnitPlatform()
}

When I run gradle build or gradle pmdMain

I got an issue:

Execution failed for task ':B:pmdMain'.
> Could not resolve all files for configuration ':B:mainPmdAuxClasspath'.
   > Could not find org.springframework.boot:spring-boot-starter-web:.
     Required by:
         project :B > project :A

Possible solution:
 - Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html

Let me highlight there is no any code used from module A in module B. Module B just takes A with implementation project(':A') and nothing more: threre is no any import, or class, just declaration in build.gradle

Why does it work so?

PMD checks only transitive dependencies. I mean if there is some usage of class TestController with @RestController spring annotation from module A in module B then it’s okay, it’s needed. But here where only implementation 'org.springframework.boot:spring-boot-starter-web' is used…

Could you please help me in that question?

You should stop using the Spring Dependency Management plugin.
It is a relict from times when Gradle did not have built-in BOM support,
by now it does more harm than good, and even its maintainer recommends
not to use it anymore, but instead the built-in BOM support using platform(...).

It solves the problem! Thank you so much
May I ask you what’s the reason of plugin spring BOM usage? Because there are a lot of documentation with the same notation as I used almost everywhere

The documentations is wrong / outdated, and people might not be aware enough that they shouldn’t use it anymore.

Only reasons to use the spring dependency management plugin nowadays that I’m aware of are if

  • you want broken by design Maven concepts that should never be invented ported over to the Gradle world
  • you want less clear reporting in build scans regarding dependencies
  • you want less clear reporting in dependencies task, dependencyInsights task and similar
  • you want strange and unexpected results in some situations when it comes to dependency resolution

Got it
Thank you!

But talking about gradle
Seems it does some dependency resolution for pmd during ‘gradle pmdMain’ task because it fails. Why? Is it needed for pmd analysis?

Some PMD rules do type resolution at analysis time to avoid false-positives and for that need the compiled classes and compile-time dependencies as far as I remember.