Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jacoco-report-aggregation plugin misses versions during resolution when io.spring.dependency-management plugin is used #353

Closed
rkrisztian opened this issue May 24, 2023 · 2 comments

Comments

@rkrisztian
Copy link

When I use the jacoco-report-aggregation plugin together with the io.spring.dependency-management plugin, and execute gw testCodeCoverageReport, I get the following error:

Execution failed for task ':testCodeCoverageReport'.
> Could not resolve all files for configuration ':allCodeCoverageReportClassDirectories'.
   > Could not find org.springframework.boot:spring-boot-starter:.
     Required by:
         project : > project :demo-common
         project : > project :demo-subproject

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 gradle/gradle#8881 (comment)), 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.

@wilkinsona
Copy link
Contributor

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.

@wilkinsona wilkinsona closed this as not planned Won't fix, can't repro, duplicate, stale May 24, 2023
@rkrisztian
Copy link
Author

Thanks for the info, and sorry that I did not understand the problem better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants