Closed rkrisztian closed 1 year ago
The problem can be reproduced without the dependency management plugin:
import org.springframework.boot.gradle.plugin.SpringBootPlugin
plugins {
id 'base'
id 'org.springframework.boot' version '3.0.5' apply false
id 'jacoco-report-aggregation'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
allprojects {
repositories {
mavenCentral()
}
}
subprojects {
pluginManager.withPlugin('java') {
apply plugin: 'jacoco'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
configurations.all {
resolutionStrategy {
eachDependency {
if (it.requested.group == 'org.springframework.boot') {
it.useVersion("3.0.5")
}
}
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.withType(Test).configureEach { useJUnitPlatform() }
tasks.withType(JacocoReport).configureEach { reports.html.required = true }
}
}
// This "withPlugin" call was added to be able to check the build without 'jacoco-report-aggregation' easily.
pluginManager.withPlugin('jacoco-report-aggregation') {
dependencies {
subprojects {
pluginManager.withPlugin('java') {
jacocoAggregation project
}
}
}
reporting {
reports {
testCodeCoverageReport(JacocoCoverageReport) {
testType = TestSuiteType.UNIT_TEST
}
}
}
tasks.named('check') {
dependsOn 'testCodeCoverageReport'
}
}
It does not occur if the resolution strategy is applied in all projects rather than in subprojects:
import org.springframework.boot.gradle.plugin.SpringBootPlugin
plugins {
id 'base'
id 'org.springframework.boot' version '3.0.5' apply false
id 'jacoco-report-aggregation'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
allprojects {
repositories {
mavenCentral()
}
}
allprojects {
configurations.all {
resolutionStrategy {
eachDependency {
if (it.requested.group == 'org.springframework.boot') {
it.useVersion("3.0.5")
}
}
}
}
}
subprojects {
pluginManager.withPlugin('java') {
apply plugin: 'jacoco'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.withType(Test).configureEach { useJUnitPlatform() }
tasks.withType(JacocoReport).configureEach { reports.html.required = true }
}
}
// This "withPlugin" call was added to be able to check the build without 'jacoco-report-aggregation' easily.
pluginManager.withPlugin('jacoco-report-aggregation') {
dependencies {
subprojects {
pluginManager.withPlugin('java') {
jacocoAggregation project
}
}
}
reporting {
reports {
testCodeCoverageReport(JacocoCoverageReport) {
testType = TestSuiteType.UNIT_TEST
}
}
}
tasks.named('check') {
dependsOn 'testCodeCoverageReport'
}
}
This also works with the dependency management plugin:
import org.springframework.boot.gradle.plugin.SpringBootPlugin
plugins {
id 'base'
id 'org.springframework.boot' version '3.0.5' apply false
id 'jacoco-report-aggregation'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
allprojects {
repositories {
mavenCentral()
}
}
allprojects {
apply plugin: 'io.spring.dependency-management'
dependencyManagement {
imports {
mavenBom SpringBootPlugin.BOM_COORDINATES
}
}
}
subprojects {
pluginManager.withPlugin('java') {
apply plugin: 'jacoco'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.withType(Test).configureEach { useJUnitPlatform() }
tasks.withType(JacocoReport).configureEach { reports.html.required = true }
}
}
// This "withPlugin" call was added to be able to check the build without 'jacoco-report-aggregation' easily.
pluginManager.withPlugin('jacoco-report-aggregation') {
dependencies {
subprojects {
pluginManager.withPlugin('java') {
jacocoAggregation project
}
}
}
reporting {
reports {
testCodeCoverageReport(JacocoCoverageReport) {
testType = TestSuiteType.UNIT_TEST
}
}
}
tasks.named('check') {
dependsOn 'testCodeCoverageReport'
}
}
I think this will have to be addressed in the jacoco-report-aggregation
plugin. It appears to be resolving dependencies from sub-projects in a way that is incompatible with using a resolution strategy to configure dependency versions.
Thanks for the info, and sorry that I did not understand the problem better.
When I use the
jacoco-report-aggregation
plugin together with theio.spring.dependency-management plugin
, and executegw testCodeCoverageReport
, I get the following error:Expected Behavior
There should be no resolution issues just by introducing the JaCoCO report aggregation plugin in a Spring Boot project.
Current Behavior
See error above.
Context
My company develops Spring Boot applications. One of the major problems I am having is figuring out the most ideal configuration for a JaCoCo report that does not miss coverage when tests cover code across subprojects, and is compatible with SonarQube. While I found one that works (and explained everything at https://github.com/gradle/gradle/issues/8881#issuecomment-1495945301), it would be better to use a configuration that requires less code and is probably more future proof, i.e., by using the
jacoco-report-aggregation
plugin. But right now I'm stuck midway at reaching that solution because of resolution issues.It's not just my problem. See https://stackoverflow.com/questions/73727598/jacoco-report-aggregation-plugin-spring-dependency-management where others faced a similar issue. Their workaround they found was to use specific versions, which I don't want to enforce on my company's projects.
Steps to Reproduce
See demo project aggregation-bug.zip. Type
gw testCodeCoverageReport
. (Sorry next time I'll try out the Gradle issue reproducer.)Your Environment
Linux with Azul JDK 17, but shouldn't matter much.