Why does the version set by useVersion in the resolutionStrategy not propagate? - spring-boot

I am using the Spring Boot Gradle plugin and its dependency management to manage some of my own dependencies across project so I do not need to add an explicit version in the build.gradle.
dependencyManagement {
dependencies {
dependency "foo.bar:my-own-library:12.1"
}
}
The problem is that I need another version "11.9" beside the version "12.1" and that I wanted the plugin to pick the correct version based on a variable.
So I added a resolutioStrategy and some variables in ext:
dependencyManagement {
dependencies {
dependency "foo.bar:our-own-library:12.1"
}
resolutionStrategy {
eachDependency { details ->
//find available version based on src_compat
//set the new version to use via
details.useVersion(newVersion)
// details.target.version yields updated version
}
}
}
ext {
src_compat = 11
extra_versions = ["foo.bar:my-own-library" : ["11.9"]]
}
The target version is set correctly every time but than the old version (12.1) is used for every configuration.
The configurations have no other custom resolutionstrategy.
My assumption was the resolutionStrategy of the plugin is able to override every version when the dependency management of the plugin is used.
Is the resolutionStrategy able to override all versions or do I have to move it the 'normal' gradle configurations?

There's some information about this in the dependency management plugin's documentation.
The dependency management resolution strategy only applies to the plugin's internal configurations, such as those that it uses to resolve the Maven boms that you have imported. As you suspected, if you want the resolution strategy to apply to the resolution of your project's dependencies, you should move it to the normal Gradle configurations.

Related

Having trouble with Gradle dependencies not updating

I have a project with 3 common jars shared across multiple repositories. I'm using Intellij 2019.4. In my gradle build, I included the following method:
dependencyManagement {
resolutionStrategy {
// don't cache SNAPSHOT modules; always retrieve them from the maven cache
cacheChangingModulesFor 0, 'seconds'
}
}
That's supposed to tell Gradle not to cache snapshots, but mine are still being cached. I build and install one of the common jars, and the maven repo has it, but the Gradle cache still has a jar from over 24 hours ago. Is there a different method I should be using? I want Gradle to ALWAYS use what's in the .m2 repo.
Gradle will only search for modules in the declared repositories.
This means that if you need a library, SNAPSHOT or not, from you local Maven repository, you need to declare it as a repository in Gradle.
repositories {
mavenLocal() {
content {
includeModule("my.org", "someLib")
}
}
// other repositories
}
However, there are caveats in adding mavenLocal() to your repositories, so make sure to use repository content filtering to only search your local Maven repo for those SNAPSHOT dependencies, as shown above.
Try to add changing = true into individual SNAPSHOT dependencies' configClosure.
implementation("group:module:1.0-SNAPSHOT") {changing = true}
Then cacheChangingModulesFor should apply to them:
configurations.all() {
resolutionStrategy {
cacheChangingModulesFor 0, "seconds"
}
}
With version latest.integration, this would require the build-number added into the version - but, this would keep the build reproducible, since one can switch back to the previous build of the library.
There also is a CLI option --refresh-dependencies, which refreshes them all.
The Gradle manual explains it, too: Declaring a changing version.
Forcibly deleting them before build would be another option.

how to declare dependency version in one place for many gradle projects

I work on a project with multiple grails services, plugins and libraries, all built with gradle with their dependencies declared in build.gradle files, one per project, this makes sense, I hope.
In maven I used to be able to declare versions of all dependencies in one parent project pom, or a pom template, and only include the dependencies in the projects that required them without the versions. This made upgrading dependencies easy in one place. Is there a simple way to do this in gradle?
Pseudocode example:
master_template/build.gradle
dependencies {
joda-time:joda-time:2.9.1
cglib:cglib:3.2.9
javax.servlet:javax.servlet-api:3.1.0
}
service_a/build.gradle
parent: master_template
dependencies {
joda-time:joda-time
javax.servlet:javax.servlet-api
}
service_b/build.gradle
parent: master_template
dependencies {
cglib:cglib
javax.servlet:javax.servlet-api
}
You can create a multi module project like you would do in maven with a parent pom.
In order to manage the dependency in the parent, I use the spring dependency management plugin.
You parent build.gradle would look like:
subprojects {
apply plugin: "io.spring.dependency-management"
sourceCompatibility = 1.8
targetCompatibility = 1.8
check.dependsOn dependencyCheckAggregate
repositories {
mavenLocal()
jcenter()
// other repos
}
dependencyManagement {
def jacksonVersion = "2.+"
dependencies {
dependency "com.fasterxml.jackson.core:jackson-annotations:$jacksonVersion"
dependency "com.fasterxml.jackson.core:jackson-core:$jacksonVersion"
dependency "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion"
dependency "com.fasterxml.jackson.datatype:jackson-datatype-jdk8:$jacksonVersion"
dependency "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jacksonVersion"
}
}
}
Now, you can add dependencies to your submodules without specifying version.
You can easily achieve what you want by using Gradle's default apply from: 'other.gradle', so no additional plugins are needed.
In my micro-service project I'm using something like that:
common-gradle/env.gradle
apply plugin:'groovy'
ext.compile = [ 'joda-time:joda-time:2.9.1', 'cglib:cglib:3.2.9` ]
ext.testCompile = [ 'org.spockframework:spock-core:1.3-groovy-2.5' ]
common-gradle/dependencies.gradle
dependencies {
compile ext.compile
testCompile ext.testCompile
}
And the usage
service_a/build.gradle
apply from:'../common-gradle/env.gradle'
ext.compile << 'ch.qos.logback:logback-classic:1.2.3'
apply from:'../common-gradle/dependencies.gradle'
Thus each of my build.gradle files contain only 3-5 lines of critical information like project name and version.
You don't need to import the common-gradle as a project in your IDE, you can simply use symlinks to avoid using external references. Also during build on a Jenkins-like pipeline, the only thing you have to do is to check out the common-gradle repo into your working dir.

Gradle with a local pom dependency picks up wrong version

My build.gradle references a local maven pom. I have enabled the mavenLocal() repository and have added the jar as a compile time dependency (eg. my-local-lib, as shown below).
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
compile (group: 'com.company', name: 'my-local-lib', version: '1.0-SNAPSHOT')
}
Gradle indeed picks it up and adds it as a dependency. My-local-lib, however, is itself dependent on another library as specified in its pom.xml, but gradle fails to pick up the correct version specified in the pom.xml, and instead chooses a much earlier version. This particular jar dependency is not a dependency on any other library.
Is this a known issue? Could it be due to my-local-lib being a SNAPSHOT version? Is there a way that I can enforce gradle to respect the versions specified in the libraries?
Try to add the following piece of code:
configurations.all {
resolutionStrategy {
cacheChangingModulesFor 0, 'seconds'
}
}
to build.gradle script.

How to let gradle always download the latest version of a dependency?

We have a custom gradle plugin, which is applied to all the projects we have. Since the plugin is released every several days, I don't want to update all the codebase to change it to use the latest version of the plugin.
How to declare it in gradle to ask it always get the latest version of the dependency?
I tried:
dependencies {
classpath "com:my-plugin:[1.0.0,)"
}
or
dependencies {
classpath "com:my-plugin:+"
}
They can get the latest version the first time, but won't get the newer one again.
as a default, once gradle resolved a dynamic dependency, gradle won't check for newer versions for 24h. you have different options to influence this. one option is to run your build with --refresh-dependencies or you customize the TTL in your build script. E.g:
configurations.all {
resolutionStrategy.cacheDynamicVersionsFor 10, 'minutes'
}
The following script should do the job:
apply plugin: 'java'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.google.inject:guice:latest.release'
}
}
Check out the docs here.
Another option is to go for snapshot publishing and configure dependency resolver to check seconds if the library changes so often.

Gradle: Overriding Dependency with Different Name

I am trying to import org.scalatra:scalatra-atmosphere:2.2.0-RC3 into a Scala 2.10 project. The issue is that this package depends on the two non-Scala-versioned packages com.typesafe.akka:akka-actor:2.0.4 and com.typesafe.akka:akka-testkit:2.0.4 (org.scala-lang:scala-library:2.9.2 and org.scalatra:scalatra-json:2.2.0-RC3 should work fine, as they will go to newest). As far as I can tell, the Akka dependencies do not exist on Maven Central, so we have broken packages.
I would like to override org.scalatra:scalatra-atmosphere:2.2.0-RC3's dependencies by hand by replacing the non-Scala-versioned packages with Scala-versioned packages that actually exist:
configurations.all {
resolutionStrategy {
eachDependency { details ->
if (details.requested.group == 'com.typesafe.akka') {
details.requested.name += "_$scalaVersion"
details.useVersion '2.1.0'
}
}
}
}
Unfortunately, this technique appears to be explicitly disallowed as of Gradle 1.4:
What went wrong:
Could not resolve all dependencies for configuration ':compile'.
> new ModuleRevisionId MUST have the same ModuleId as original one. original = com.typesafe.akka#akka-actor new = com.typesafe.akka#akka-actor_2.10
Is there a legitimate way to work around this issue?
Only version changes are supported in 1.4, 1.5 is due to contain support for changing the other attributes of a dependency.
I think your options are variations on excluding the specific dependency and adding it back in by hand. Examples can be found in the docs
dependencies {
compile("org.scalatra:scalatra-atmosphere:2.2.0-RC3) {
exclude group: 'com.typesafe.akka', module: 'akka-actor'
exclude group: 'com.typesafe.akka', module: 'akka-testkit'
}
// assuming you have this available in a repository your build is configured to resolve against
compile 'com.typesafe.akka:akka-actor:2.0.4-MY.LOCAL.VERSION'
}

Resources