Test-report-aggregation plugin does not see versions provided by Spring dependency-management plugin

Hi. I would like to use the test-report-aggregation plugin in my multi-module project. It’s a basic Spring-boot-based app.
Suppose I have a hello-world Spring Boot app which consist of 2 modules: library and the app itself. If I want to collect test results with test-report-aggregation plugin, I will get a bunch of “Cannot resolve external dependency” errors:

Execution failed for task ':test-results:testAggregateTestReport'.
> Could not resolve all files for configuration ':test-results:aggregateTestReportResults'.
   > Cannot resolve external dependency org.springframework.boot:spring-boot-starter-actuator because no repositories are defined.
     Required by:
         project :test-results > project :application
   > Cannot resolve external dependency org.springframework.boot:spring-boot-starter-web because no repositories are defined.
     Required by:
         project :test-results > project :application
   > Cannot resolve external dependency org.springframework.boot:spring-boot-starter because no repositories are defined.
     Required by:
         project :test-results > project :library

Why? I think that’s because versions in Spring Boot-based projects are not defined explicitly and are managed by Spring’s Dependency Management Plugin ( io.spring.dependency-management).


How to reproduce:

  • get the code:
git clone https://github.com/spring-guides/gs-multi-module
cd gs-multi-module
git checkout b5b978181a8c8f135384c80ee844ca9c01017e24
cd complete
  • set the latest Gradle version in gradle-wrapper.properties (8.1.1 as for now)
  • optionally set the most recent version of Spring boot build.gradle of each module (3.0.6 as for now)
  • add new module aggregated-test-results into settings.grale
  • create a aggregated-test-results/build.gradle.kts with the following content:
plugins {
    base
    id("test-report-aggregation")
}

dependencies {
    testReportAggregation(project(":application"))
    testReportAggregation(project(":library"))
}

reporting {
    reports {
        @Suppress("UnstableApiUsage", "UNUSED_VARIABLE")
        val testAggregateTestReport by creating(AggregateTestReport::class) {
            testType.set(TestSuiteType.UNIT_TEST)
        }
    }
}
  • execute ./gradlew -p test-results testAggregateTestReport and here are the “Cannot resolve external dependency” errors.

Adding id("io.spring.dependency-management") version "1.1.0" to aggregated-test-results/build.gradle.kts does not fix the problem.

Is there any way to make it work or should I rather create a bug-report (or feature request) to enable compatibility of test-report-aggregation with io.spring.dependency-management?

If it indeed is due to the Spring dependency management plugin, don’t use it.

Even if it is not due to the Spring dependency management plugin, don’t use it.

It is a legacy relict of times when Gradle did not have built-in BOM support.
Even the maintainer of that plugin recommends not to use it anymore, but instead use the built-in BOM support using platform(...).

1 Like

Even the maintainer of that plugin recommends not to use it anymore, but instead use the built-in BOM support

@Vampire could you please provide any references for that recommendation from the maintainer? I’ve read the whole documentation for Spring’s dependency management plugin and did not find any recommendation to switch to Gradle’s native dependency management mechanism.

Only Spring Boot plugin’s docs (which is a different plugin) mentions that there are 2 ways to manage dependencies:

To manage dependencies in your Spring Boot application, you can either apply the io.spring.dependency-management plugin or use Gradle’s native bom support. The primary benefit of the former is that it offers property-based customization of managed versions, while using the latter will likely result in faster builds.

And each of 2 ways has it’s benefits: i.e. Spring plugin supports overriding version of imported BOMs with properties, while Gradle’s native approach does not seem to support this. The doc does not say that you should prefer one way over the other, it just describes 2 possible ways. Also I think that if Spring dependency management plugin was deprecated (or not recommended), it would not be used in fresh projects generated at start.spring.io :thinking:

You can import BOM in the following way, of course implementation can be replaced by other APIs

dependencies {
        implementation platform("org.springframework.boot:spring-boot-dependencies:$springbootversion")
}

I prefer custom keywords to handle BOM introduction,About this you can view my source code

dependencies {
        management platform(project(":spring-extension-dependencies"))
}

The documentation for this gradle platform

Good luck

1 Like

could you please provide any references for that recommendation from the maintainer?

Sure: What is the proper way to apply a BOM in a library project i gradle-community #dependency-management

The doc does not say that you should prefer one way over the other, it just describes 2 possible ways.

I didn’t say the Spring docs, I said the maintainer of that plugin.

Also I think that if Spring dependency management plugin was deprecated (or not recommended), it would not be used in fresh projects generated at start.spring.io

Probably same reason it is not clarified in the docs. Either because other person maintaining it, or simply lack of time for such a relatively important change. Feel free to send them two pull requests. :slight_smile:

Spring plugin supports overriding version of imported BOMs with properties, while Gradle’s native approach does not seem to support this.

There are ways, just not by setting a property. And for that possibility you earn many problems and quirks you don’t have with the built-in support.

1 Like