tobi
tobi

Reputation: 2012

Library version in gradle downgraded

When executing (in gradle 6.5)

./gradlew dependencyInsight --dependency groovy-testng --configuration testRuntimeClasspath

I could find groovy-testng comes from groovy-all library which was added to our build.gradle. I wanted to update version of groovy-testng, so I decided to update groovy-all which, according to mvnrepository, contains groovy-testng in version 3.0.4, but still the version of groovy-testng was the old one and gradle didn't resolve it to the latest version:

org.codehaus.groovy:groovy-testng:2.5.12 (selected by rule)
   variant "runtime" [
      org.gradle.status              = release (not requested)
      org.gradle.usage               = java-runtime
      org.gradle.libraryelements     = jar
      org.gradle.category            = library

      Requested attributes not found in the selected variant:
         org.gradle.dependency.bundling = external
         org.gradle.jvm.version         = 11
   ]

org.codehaus.groovy:groovy-testng:3.0.4 -> 2.5.12
\--- org.codehaus.groovy:groovy-all:3.0.4
     \--- testRuntimeClasspath

I have found the line selected by rule but couldn't find any ResolutionStrategy in my project, so I started to comment out and see what causes this. It turned out it's a plugin org.springframework.boot together with io.spring.dependency-management causes this version to be downgraded. Why? And why only when both of them are included? I assume these plugins define some ResolutionStrategy? What is the easiest way to find out where is the ResolutionStrategy coming from?

Upvotes: 1

Views: 1294

Answers (1)

Cisco
Cisco

Reputation: 23060

The Spring Dependency Management plugin is rather heavy handed. If were you build your project with --info or -i, you will see a bunch of these logs:

Applying dependency management to configuration 'bootArchives' in project 'demo'
Applying dependency management to configuration 'archives' in project 'demo'
Applying dependency management to configuration 'default' in project 'demo'
Applying dependency management to configuration 'compile' in project 'demo'
Applying dependency management to configuration 'implementation' in project 'demo'
Applying dependency management to configuration 'runtime' in project 'demo'
Applying dependency management to configuration 'compileOnly' in project 'demo'

From my experience, the dependency management plugin will win/force itself to win.

I can see in your snippet, that you wanted 3.0.4 of Groovy, but Gradle resolved 2.5.12. If you look at the Spring Boot Dependencies BOM, you will see that 2.5.12 is the current version for Spring Boot 2.3.1: https://github.com/spring-projects/spring-boot/blob/2.3.x/spring-boot-project/spring-boot-dependencies/build.gradle#L365..L371

The Spring Boot Gradle plugin detects if the Spring dependency management plugin is present, and if so, configures the plugin to import the Spring Boot dependencies BOM: https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/DependencyManagementPluginAction.java

From looking at the BOM: https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-dependencies/2.3.1.RELEASE/spring-boot-dependencies-2.3.1.RELEASE.pom

You should be able to override the Groovy version like so:

ext {
  set("groovy.version", "3.0.4")
}

The Spring dependency management plugin should pick that up and apply 3.0.4

If that doesn't solve your issue, then you have other plugins or configuration at play here that you will need to figure out.

I also suggest watching Managing Dependencies for Spring Projects with Gradle to learn the differences between Spring dependency management plugin and Gradle's native dependency management.

Upvotes: 4

Related Questions