From 00cd8945d5a44df9e885e8b2903049ab7f9d57af Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 30 Jul 2020 20:53:44 +0100 Subject: [PATCH] Document how to use Gradle's native bom support Closes gh-21570 --- .../src/docs/asciidoc/getting-started.adoc | 2 +- .../docs/asciidoc/managing-dependencies.adoc | 71 +++++++++++++++++-- .../configure-platform.gradle | 28 ++++++++ .../configure-platform.gradle.kts | 30 ++++++++ .../custom-version-with-platform.gradle | 33 +++++++++ .../custom-version-with-platform.gradle.kts | 35 +++++++++ ...anagingDependenciesDocumentationTests.java | 13 ++++ 7 files changed, 204 insertions(+), 8 deletions(-) create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/managing-dependencies/configure-platform.gradle create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/managing-dependencies/configure-platform.gradle.kts create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/managing-dependencies/custom-version-with-platform.gradle create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/managing-dependencies/custom-version-with-platform.gradle.kts diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/getting-started.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/getting-started.adoc index a609169653..2cb7a5d2aa 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/getting-started.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/getting-started.adoc @@ -82,7 +82,7 @@ endif::[] Applied in isolation the plugin makes few changes to a project. Instead, the plugin detects when certain other plugins are applied and reacts accordingly. For example, when the `java` plugin is applied a task for building an executable jar is automatically configured. -A typical Spring Boot project will apply the {groovy-plugin}[`groovy`], {java-plugin}[`java`], or {kotlin-plugin}[`org.jetbrains.kotlin.jvm`] plugin and the {dependency-management-plugin}[`io.spring.dependency-management`] plugin as a minimum. +A typical Spring Boot project will apply the {groovy-plugin}[`groovy`], {java-plugin}[`java`], or {kotlin-plugin}[`org.jetbrains.kotlin.jvm`] plugin as a minimum and also use the {dependency-management-plugin}[`io.spring.dependency-management`] plugin or Gradle's native bom support for dependency management. For example: diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/managing-dependencies.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/managing-dependencies.adoc index 60f9c096b6..bf8c96002c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/managing-dependencies.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/managing-dependencies.adoc @@ -1,5 +1,12 @@ [[managing-dependencies]] == Managing Dependencies +To manage dependencies in your Spring Boot application, you can either apply the {dependency-management-plugin}[`io.spring.dependency-management`] plugin or, if you are using Gradle 6 or later, use Gradle's native bom support. +The primary benefit of the former is that it offers property-based customization of managed versions, while using the latter will likely result in faster builds. + + + +[[managing-dependencies-dependency-management-plugin]] +=== Managing Dependencies with the Dependency Management Plugin When you apply the {dependency-management-plugin}[`io.spring.dependency-management`] plugin, Spring Boot's plugin will automatically <> 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. @@ -18,8 +25,9 @@ include::../gradle/managing-dependencies/dependencies.gradle.kts[tags=dependenci ---- -[[managing-dependencies-customizing]] -=== Customizing Managed Versions + +[[managing-dependencies-dependency-management-plugin-customizing]] +==== Customizing Managed Versions The `spring-boot-dependencies` bom that is automatically imported when the dependency management plugin is applied uses properties to control the versions of the dependencies that it manages. Browse the {version-properties-appendix}[`Dependency versions Appendix`] in the Spring Boot reference for a complete list of these properties. @@ -38,14 +46,13 @@ include::../gradle/managing-dependencies/custom-version.gradle[tags=custom-versi include::../gradle/managing-dependencies/custom-version.gradle.kts[tags=custom-version] ---- - WARNING: Each Spring Boot release is designed and tested against a specific set of third-party dependencies. Overriding versions may cause compatibility issues and should be done with care. -[[managing-dependencies-using-in-isolation]] -=== Using Spring Boot's Dependency Management in Isolation +[[managing-dependencies-dependency-management-plugin-using-in-isolation]] +==== Using Spring Boot's Dependency Management in Isolation Spring Boot's dependency management can be used in a project without applying Spring Boot's plugin to that project. The `SpringBootPlugin` class provides a `BOM_COORDINATES` constant that can be used to import the bom without having to know its group ID, artifact ID, or version. @@ -120,6 +127,56 @@ include::../gradle/managing-dependencies/configure-bom-with-plugins.gradle.kts[t ---- -[[managing-dependencies-learning-more]] -=== Learning More + +[[managing-dependencies-dependency-management-plugin-learning-more]] +==== Learning More To learn more about the capabilities of the dependency management plugin, please refer to its {dependency-management-plugin-documentation}[documentation]. + + + +[[managing-dependencies-gradle-bom-support]] +=== Managing Dependencies with Gradle's Bom Support +Gradle allows a bom to be used to manage a project's versions by declaring it as a `platform` or `enforcedPlatform` dependency. +A `platform` dependency treats the versions in the bom as recommendations and other versions and constraints in the dependency graph may cause a version of a dependency other than that declared in the bom to be used. +An `enforcedPlatform` dependency treats the versions in the bom as requirements and they will override any other version found in the dependency graph. + +The `SpringBootPlugin` class provides a `BOM_COORDINATES` constant that can be used to declare a dependency upon Spring Boot's bom without having to know its group ID, artifact ID, or version, as shown in the following example: + +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy +---- +include::../gradle/managing-dependencies/configure-platform.gradle[tags=configure-platform] +---- + +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/managing-dependencies/configure-platform.gradle.kts[tags=configure-platform] +---- + +A platform or enforced platform will only constrain the versions of the configuration in which it has been declared or that extend from the configuration in which it has been declared. +As a result, in may be necessary to declare the same dependency in more than one configuration. + + + +[[managing-dependencies-gradle-bom-support-customizing]] +==== Customizing Managed Versions +When using Gradle's bom support, you cannot use the properties from `spring-boot-dependencies` to control the versions of the dependencies that it manages. +Instead, you must use one of the mechanisms that Gradle provides. +One such mechanism is a resolution strategy. +SLF4J's modules are all in the `org.slf4j` group so their version can be controlled by configuring every dependency in that group to use a particular version, as shown in the following example: + +[source,groovy,indent=0,subs="verbatim",role="primary"] +.Groovy +---- +include::../gradle/managing-dependencies/custom-version-with-platform.gradle[tags=custom-version] +---- + +[source,kotlin,indent=0,subs="verbatim",role="secondary"] +.Kotlin +---- +include::../gradle/managing-dependencies/custom-version-with-platform.gradle.kts[tags=custom-version] +---- + +WARNING: Each Spring Boot release is designed and tested against a specific set of third-party dependencies. +Overriding versions may cause compatibility issues and should be done with care. diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/managing-dependencies/configure-platform.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/managing-dependencies/configure-platform.gradle new file mode 100644 index 0000000000..25a265efe1 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/managing-dependencies/configure-platform.gradle @@ -0,0 +1,28 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '{gradle-project-version}' +} + +// tag::configure-platform[] +dependencies { + implementation platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES) +} +// end::configure-platform[] + +dependencies { + implementation "org.springframework.boot:spring-boot-starter" +} + +repositories { + maven { url 'file:repository' } +} + +configurations.all { + resolutionStrategy { + eachDependency { + if (it.requested.group == 'org.springframework.boot') { + it.useVersion 'TEST-SNAPSHOT' + } + } + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/managing-dependencies/configure-platform.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/managing-dependencies/configure-platform.gradle.kts new file mode 100644 index 0000000000..30cfc8ab04 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/managing-dependencies/configure-platform.gradle.kts @@ -0,0 +1,30 @@ +plugins { + java + id("org.springframework.boot") version "{gradle-project-version}" +} + +// tag::configure-platform[] +dependencies { + implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)) +} +// end::configure-platform[] + +dependencies { + implementation("org.springframework.boot:spring-boot-starter") +} + +repositories { + maven { + url = uri("file:repository") + } +} + +configurations.all { + resolutionStrategy { + eachDependency { + if (requested.group == "org.springframework.boot") { + useVersion("TEST-SNAPSHOT") + } + } + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/managing-dependencies/custom-version-with-platform.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/managing-dependencies/custom-version-with-platform.gradle new file mode 100644 index 0000000000..d877c3df16 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/managing-dependencies/custom-version-with-platform.gradle @@ -0,0 +1,33 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '{gradle-project-version}' +} + +dependencies { + implementation platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES) + implementation "org.slf4j:slf4j-api" +} + +repositories { + maven { url 'file:repository' } +} + +configurations.all { + resolutionStrategy { + eachDependency { + if (it.requested.group == 'org.springframework.boot') { + it.useVersion 'TEST-SNAPSHOT' + } + } + } +} + +// tag::custom-version[] +configurations.all { + resolutionStrategy.eachDependency { DependencyResolveDetails details -> + if (details.requested.group == 'org.slf4j') { + details.useVersion '1.7.20' + } + } +} +// end::custom-version[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/managing-dependencies/custom-version-with-platform.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/managing-dependencies/custom-version-with-platform.gradle.kts new file mode 100644 index 0000000000..a0262204e9 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/managing-dependencies/custom-version-with-platform.gradle.kts @@ -0,0 +1,35 @@ +plugins { + java + id("org.springframework.boot") version "{gradle-project-version}" +} + +dependencies { + implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)) + implementation("org.slf4j:slf4j-api") +} + +repositories { + maven { + url = uri("file:repository") + } +} + +configurations.all { + resolutionStrategy { + eachDependency { + if (requested.group == "org.springframework.boot") { + useVersion("TEST-SNAPSHOT") + } + } + } +} + +// tag::custom-version[] +configurations.all { + resolutionStrategy.eachDependency { + if (requested.group == "org.slf4j") { + useVersion("1.7.20") + } + } +} +// end::custom-version[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/ManagingDependenciesDocumentationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/ManagingDependenciesDocumentationTests.java index 4a144b6b19..d2608379fa 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/ManagingDependenciesDocumentationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/ManagingDependenciesDocumentationTests.java @@ -63,4 +63,17 @@ class ManagingDependenciesDocumentationTests { .contains("org.springframework.boot:spring-boot-starter TEST-SNAPSHOT")); } + @TestTemplate + void configurePlatform() { + assertThat(this.gradleBuild.script("src/docs/gradle/managing-dependencies/configure-platform") + .build("dependencies", "--configuration", "compileClasspath").getOutput()) + .contains("org.springframework.boot:spring-boot-starter "); + } + + @TestTemplate + void customManagedVersionsWithPlatform() { + assertThat(this.gradleBuild.script("src/docs/gradle/managing-dependencies/custom-version-with-platform") + .build("dependencies", "--configuration", "compileClasspath").getOutput()).contains("1.7.20"); + } + }