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

Document how to declare a dependency using a provider to avoid problems with importedProperties and managedVersions causing premature bom resolution that interferes with subsequent dependency management and dependency configuration #193

Open
andersonkyle opened this issue Nov 30, 2017 · 4 comments

Comments

@andersonkyle
Copy link

Here is the relevant snippet from my build.gradle file that reproduces this issue:

dependencies {
	compile('org.springframework.boot:spring-boot-starter-web')


	compile('io.dropwizard.metrics:metrics-core')


	//
	//Try switching switching between these two dependencies and checking 'gradlew dependencyManagement' for whether the Spring Cloud BOM was imported or not.
	//
	compile 'io.dropwizard.metrics:metrics-jvm:' + dependencyManagement.managedVersions['io.dropwizard.metrics:metrics-core']
	//compile 'io.dropwizard.metrics:metrics-jvm'


	testCompile('org.springframework.boot:spring-boot-starter-test')
}


dependencyManagement {
	imports {
		mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
	}
}

The problem occurs when I call the dependencyManagement API from within a dependency {} declaration.

compile 'io.dropwizard.metrics:metrics-jvm:' + dependencyManagement.managedVersions['io.dropwizard.metrics:metrics-core']

If this API call is removed, the mavenBom is imported as expected.

Here is an example repo. To test whether the BOM is imported or not, use this command:

gradlew dependencyManagement

Spring Boot alone only contains about 5 Spring Cloud dependencies, so that's all you should see in the list.
When you remove the API call mentioned above, you'll see dozens of Spring Cloud dependencies coming from the Spring Cloud BOM.

NOTE: Ordering seems to be a factor as if you move the dependencyManagement {} section above the dependencies {} section, it works as expected, even when calling the dependencyManagement API within a dependency declaration.

@wilkinsona
Copy link
Contributor

The problem is that calling dependencyManagement.managedVersions causes the imported boms to be resolved. This marks the dependency management as resolved. The subsequent import of the Spring Cloud bom doesn't change this so it's effectively ignored. The fix is to reset the resolved flag each time a bom import is added.

There's a broader problem here, though. Using dependencyManagement.managedVersions has the unwanted side-effect of causing dependency resolution (for the imported boms) before task execution occurs. It would be good to be able to avoid that but I'm not sure how to do so. The best idea I can come up with is to use a placeholder for the version that's then spotted by a resolution strategy and replaced with the property version.

@wilkinsona
Copy link
Contributor

wilkinsona commented Sep 19, 2018

The same broader problem also applies to dependencyManagement.importedProperties which is discussed in #56. Using a placeholder may also work in that case.

@wilkinsona wilkinsona changed the title mavenBom silently fails to import if dependencyManagement API is used within a dependency declaration Using dependencyManagement importedProperties and managedVersions causes premature bom resolution and interferes with subsequent dependency management and dependency configuration Sep 19, 2018
@jjathman
Copy link

jjathman commented Oct 3, 2018

To add another related use case, I would like to specify a version, but only if the version I am specifying is newer than the one that would otherwise be used. We would like to use the newer version because it includes a security fix, but whenever Spring Boot starts including a version that is newer than the one specified we would just want to use that. I attempted to use the dependencyManagement API like others here but ran in to similar problems.

@wilkinsona wilkinsona changed the title Using dependencyManagement importedProperties and managedVersions causes premature bom resolution and interferes with subsequent dependency management and dependency configuration Document how to declare a dependency using a provider to avoid problems with importedProperties and managedVersions causing premature bom resolution that interferes with subsequent dependency management and dependency configuration Jun 30, 2022
@wilkinsona
Copy link
Contributor

Gradle 6.5 has added support for declaring dependencies using a Provider. The provider's evaluated lazily which avoids the problem of prematurely resolving the imported boms. The problematic dependency in the original example can be fixed by writing it like this:

implementation provider { 'io.dropwizard.metrics:metrics-jvm:' + dependencyManagement.managedVersions['io.dropwizard.metrics:metrics-core'] }

I'll turn this into a documentation issue for 1.0.x.

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