kaido
kaido

Reputation: 351

how to choose between versions in build.gradle

if you have a build.gradle file with the line implementation 'org.springframework.boot:spring-boot-starter-web', how do you choose the version of the jar it downloads so that you get the latest one? I've seen a project where it is a 2.2.4 release, but in another project I've seen the same line with a 2.2.5 release.

Upvotes: 2

Views: 3841

Answers (2)

Thomas K.
Thomas K.

Reputation: 6770

Since you dropped the name Spring Boot, I assume the project has been generated Spring Initializr. A project generated with the Initializr has two plugins applied:

io.spring.dependency-management is Spring's opinionated way to provide Maven-like dependency management to Gradle builds. It allows to declare dependency versions once and then omit the version when declaring the actual dependency.

The org.springframework.boot plugin does the following:

When you apply the io.spring.dependency-management plugin, Spring Boot’s plugin will automatically import the spring-boot-dependencies bom from the version of Spring Boot that you are using. This provides a similar dependency management experience to the one that’s enjoyed by Maven users. For example, it allows you to omit version numbers when declaring dependencies that are managed in the bom. To make use of this functionality, simply declare dependencies in the usual way but omit the version number.

(From: Managing Dependencies)

What does that mean in practice?

When you generate a project for Spring Boot 2.1.14, your build.gradle will look similar to this:

plugins {
  id 'org.springframework.boot' version '2.1.14.RELEASE'
  id 'io.spring.dependency-management' version '1.0.9.RELEASE'
}

dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-web'
}

The org.springframework.boot plugin instructs the io.spring.dependency-management to apply the bill of materials (BOM) of Spring Boot 2.1.14. The BOM declares the following version for spring-boot-starter-web:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.1.14.RELEASE</version>
</dependency>

(From: Maven Central)

And this combination allows to declare the dependency to spring-boot-starter-web in the build.gradle without providing an actual version:

dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-web'
}

If you would change the version of the org.springframework.boot Gradle plugin, then a different version that matches the Spring Boot versions would be applied.

You may ask, why this tremendous effort?

We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss.

That's why.

Upvotes: 5

afterburner
afterburner

Reputation: 2781

One possible solution is to use lockfiles and a version of +, or a combination of major.minor.+ or major.+

 implementation 'org.springframework.boot:spring-boot-starter-web:+'

For more information on dependency locking: https://docs.gradle.org/current/userguide/dependency_locking.html

Another approach, and one I'm quite pleased with where available, is using a bill of materials, which specifies versions for a lot of dependencies, by introducing constraints. So where a dependency is used, with no version specified, as in your example, it will get the version the BOM brings in. So for the dependency below, if it is present in the BOM, it will match

implementation 'org.springframework.boot:spring-boot-starter-web

You're also free to override versions manually, by still specifying the version, should you choose to. And a BOM is like any other dependency, so you can use a mixture of lockfiles and BOMs.

Here's gradle documentation on bill of materials: https://docs.gradle.org/current/userguide/platforms.html

Upvotes: 1

Related Questions