diff --git a/spring-boot-project/spring-boot-parent/pom.xml b/spring-boot-project/spring-boot-parent/pom.xml index 8ebd82709d..ec43faa4de 100644 --- a/spring-boot-project/spring-boot-parent/pom.xml +++ b/spring-boot-project/spring-boot-parent/pom.xml @@ -26,6 +26,7 @@ 3.5.4 1.1.1 1.0-groovy-2.4 + 1.0.6.RELEASE http://github.com/spring-projects/spring-boot @@ -108,7 +109,7 @@ io.spring.gradle dependency-management-plugin - 1.0.6.RELEASE + ${dependency-management-plugin.version} jline diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/pom.xml index d90ae32ddb..c35f93ed15 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/pom.xml +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/pom.xml @@ -128,6 +128,13 @@ + + + springio + Spring IO releases repository + https://repo.spring.io/release + + windows @@ -275,6 +282,7 @@ ${github-tag} ${version-type} ${project.version} + ${dependency-management-plugin.version} @@ -283,6 +291,11 @@ asciidoctorj-pdf 1.5.0-alpha.11 + + io.spring.asciidoctor + spring-asciidoctor-extensions + 0.1.3.RELEASE + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/getting-started.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/getting-started.adoc index 4b8bfd8e99..3ef9c146fd 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/getting-started.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/getting-started.adoc @@ -6,21 +6,96 @@ To get started with the plugin it needs to be applied to your project. ifeval::["{version-type}" == "RELEASE"] The plugin is https://plugins.gradle.org/plugin/org.springframework.boot[published to Gradle's plugin portal] and can be applied using the `plugins` block: -[source,groovy,indent=0,subs="verbatim,attributes"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/getting-started/apply-plugin-release.gradle[] ---- + +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/getting-started/apply-plugin-release.gradle.kts[] +---- endif::[] ifeval::["{version-type}" == "MILESTONE"] +The plugin is published to the Spring milestones repository. For Gradle versions less +than 4.10, this means that you must apply the plugin imperatively: + [source,groovy,indent=0,subs="verbatim,attributes"] ---- include::../gradle/getting-started/apply-plugin-milestone.gradle[] ---- + +For Gradle 4.10 and above, Gradle can be configured to use the milestones repository +and it can be applied using the `plugins` block. To configure Gradle to use the milestones +repository, add the following to your `settings.gradle` (Groovy) or `settings.gradle.kts` +(Kotlin): + +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy +---- +include::../gradle/getting-started/milestone-settings.gradle[] +---- + +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/getting-started/milestone-settings.gradle.kts[] +---- + +The plugin can then be applied using the `plugins` block: + +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy +---- +include::../gradle/getting-started/apply-plugin-release.gradle[] +---- + +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/getting-started/apply-plugin-release.gradle.kts[] +---- endif::[] ifeval::["{version-type}" == "SNAPSHOT"] +The plugin is published to the Spring snapshots repository. For Gradle versions less +than 4.10, this means that you must apply the plugin imperatively: + [source,groovy,indent=0,subs="verbatim,attributes"] ---- -include::../gradle/getting-started/apply-plugin-snapshot.gradle[] +include::../gradle/getting-started/apply-plugin-milestone.gradle[] +---- + +For Gradle 4.10 and above, Gradle can be configured to use the snapshots repository +and it can be applied using the `plugins` block. To configure Gradle to use the snapshots +repository, add the following to your `settings.gradle` (Groovy) or `settings.gradle.kts` +(Kotlin): + +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy +---- +include::../gradle/getting-started/snapshot-settings.gradle[] +---- + +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/getting-started/snapshot-settings.gradle.kts[] +---- + +The plugin can then be applied using the `plugins` block: + +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy +---- +include::../gradle/getting-started/apply-plugin-release.gradle[] +---- + +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/getting-started/apply-plugin-release.gradle.kts[] ---- endif::[] @@ -34,10 +109,18 @@ A typical Spring Boot project will apply the {groovy-plugin}[`groovy`], plugin and the {dependency-management-plugin}[`io.spring.dependency-management`] plugin as a minimum. For example: -[source,groovy,indent=0,subs="verbatim,attributes"] + +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/getting-started/typical-plugins.gradle[tags=apply] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/getting-started/typical-plugins.gradle.kts[tags=apply] +---- + To learn more about how the Spring Boot plugin behaves when other plugins are applied please see the section on <>. diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/index.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/index.adoc index d16ec8fb8c..c1c8bba267 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/index.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/index.adoc @@ -37,7 +37,8 @@ Andy Wilkinson The Spring Boot Gradle Plugin provides Spring Boot support in https://gradle.org[Gradle], allowing you to package executable jar or war archives, run Spring Boot applications, and use the dependency management provided by `spring-boot-dependencies`. Spring Boot's -Gradle plugin requires Gradle 4.4 or later. +Gradle plugin requires Gradle 4.4 or later. If you choose to use the newer Kotlin DSL, +it requires Gradle 4.10 or later. In addition to this user guide, {api-documentation}[API documentation] is also available. @@ -47,4 +48,4 @@ include::packaging.adoc[] include::publishing.adoc[] include::running.adoc[] include::integrating-with-actuator.adoc[] -include::reacting.adoc[] \ No newline at end of file +include::reacting.adoc[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/integrating-with-actuator.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/integrating-with-actuator.adoc index cf140e1dca..4e5e862500 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/integrating-with-actuator.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/integrating-with-actuator.adoc @@ -10,11 +10,19 @@ build in the presence of a `META-INF/build-info.properties` file. A {build-info-javadoc}[`BuildInfo`] task is provided to generate this file. The easiest way to use the task is via the plugin's DSL: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/integrating-with-actuator/build-info-basic.gradle[tags=build-info] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/integrating-with-actuator/build-info-basic.gradle.kts[tags=build-info] +---- + + This will configure a {build-info-javadoc}[`BuildInfo`] task named `bootBuildInfo` and, if it exists, make the Java plugin's `classes` task depend upon it. The task's destination directory will be `META-INF` in the output directory of the main source set's resources @@ -45,11 +53,19 @@ By default, the generated build information is derived from the project: The properties can be customized using the DSL: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/integrating-with-actuator/build-info-custom-values.gradle[tags=custom-values] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/integrating-with-actuator/build-info-custom-values.gradle.kts[tags=custom-values] +---- + + The default value for `build.time` is the instant at which the project is being built. A side-effect of this is that the task will never be up-to-date. As a result, builds will take longer as more tasks, including the project's tests, will have to be executed. @@ -59,7 +75,15 @@ than the accuracy of the `build.time` property, set `time` to `null` or a fixed Additional properties can also be added to the build information: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/integrating-with-actuator/build-info-additional.gradle[tags=additional] ---- + +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/integrating-with-actuator/build-info-additional.gradle.kts[tags=additional] +---- + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/managing-dependencies.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/managing-dependencies.adoc index f3f0d2893a..cb35083696 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/managing-dependencies.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/managing-dependencies.adoc @@ -10,11 +10,17 @@ 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: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim",role="primary"] +.Groovy ---- include::../gradle/managing-dependencies/dependencies.gradle[tags=dependencies] ---- +[source,kotlin,indent=0,subs="verbatim",role="secondary"] +.Kotlin +---- +include::../gradle/managing-dependencies/dependencies.gradle.kts[tags=dependencies] +---- [[managing-dependencies-customizing]] @@ -28,11 +34,19 @@ for a complete list of these properties. To customize a managed version you set its corresponding property. For example, to customize the version of SLF4J which is controlled by the `slf4j.version` property: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim",role="primary"] +.Groovy ---- include::../gradle/managing-dependencies/custom-version.gradle[tags=custom-version] ---- +[source,kotlin,indent=0,subs="verbatim",role="secondary"] +.Kotlin +---- +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. @@ -50,21 +64,41 @@ artifact ID, or version. First, configure the project to depend on the Spring Boot plugin but do not apply it: ifeval::["{version-type}" == "RELEASE"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/managing-dependencies/depend-on-plugin-release.gradle[] ---- + +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/managing-dependencies/depend-on-plugin-release.gradle.kts[] +---- endif::[] ifeval::["{version-type}" == "MILESTONE"] -[source,groovy,indent=0,subs="verbatim,attributes"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/managing-dependencies/depend-on-plugin-milestone.gradle[] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/managing-dependencies/depend-on-plugin-release.gradle.kts[] +---- endif::[] ifeval::["{version-type}" == "SNAPSHOT"] -[source,groovy,indent=0,subs="verbatim,attributes"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/managing-dependencies/depend-on-plugin-snapshot.gradle[] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/managing-dependencies/depend-on-plugin-release.gradle.kts[] +---- endif::[] The Spring Boot plugin's dependency on the dependency management plugin means that you @@ -74,11 +108,30 @@ management plugin as Spring Boot uses. Apply the dependency management plugin and then configure it to import Spring Boot's bom: -[source,groovy,indent=0,subs="verbatim,attributes"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/managing-dependencies/configure-bom.gradle[tags=configure-bom] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/managing-dependencies/configure-bom.gradle.kts[tags=configure-bom] +---- + + +The Kotlin code above is a bit awkward. That's because we're using the imperative way of +applying the dependency management plugin. + +We can make the code less awkward by applying the plugin from the root parent project, or +by using the `plugins` block as we're doing for the Spring Boot plugin. A downside of this +method is that it forces us to specify the version of the dependency management plugin: + +[source,kotlin,indent=0,subs="verbatim,attributes"] +---- +include::../gradle/managing-dependencies/configure-bom-with-plugins.gradle.kts[tags=configure-bom] +---- [[managing-dependencies-learning-more]] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/packaging.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/packaging.adoc index 9fd3643fe8..c77066a4a6 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/packaging.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/packaging.adoc @@ -33,11 +33,19 @@ A war file can be packaged such that it can be executed using `java -jar` and de to an external container. To do so, the embedded servlet container dependencies should be added to the `providedRuntime` configuration, for example: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/packaging/war-container-dependency.gradle[tags=dependencies] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/packaging/war-container-dependency.gradle.kts[tags=dependencies] +---- + + This ensures that they are package in the war file's `WEB-INF/lib-provided` directory from where they will not conflict with the external container's own classes. @@ -54,20 +62,36 @@ By default, when the `bootJar` or `bootWar` tasks are configured, the `jar` or ` tasks are disabled. A project can be configured to build both an executable archive and a normal archive at the same time by enabling the `jar` or `war` task: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/packaging/boot-jar-and-jar.gradle[tags=enable-jar] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/packaging/boot-jar-and-jar.gradle.kts[tags=enable-jar] +---- + + To avoid the executable archive and the normal archive from being written to the same location, one or the other should be configured to use a different location. One way to do so is by configuring a classifier: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/packaging/boot-jar-and-jar.gradle[tags=classifier] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/packaging/boot-jar-and-jar.gradle.kts[tags=classifier] +---- + + [[packaging-executable-configuring]] === Configuring executable archive packaging @@ -88,34 +112,63 @@ the task's classpath. The main class can also be configured explicitly using the task's `mainClassName` property: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/packaging/boot-jar-main-class.gradle[tags=main-class] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/packaging/boot-jar-main-class.gradle.kts[tags=main-class] +---- + + Alternatively, the main class name can be configured project-wide using the `mainClassName` property of the Spring Boot DSL: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/packaging/spring-boot-dsl-main-class.gradle[tags=main-class] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/packaging/spring-boot-dsl-main-class.gradle.kts[tags=main-class] +---- + + If the {application-plugin}[`application` plugin] has been applied its `mainClassName` project property can be used for the same purpose: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/packaging/application-plugin-main-class.gradle[tags=main-class] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/packaging/application-plugin-main-class.gradle.kts[tags=main-class] +---- + Lastly, the `Start-Class` attribute can be configured on the task's manifest: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/packaging/boot-jar-manifest-main-class.gradle[tags=main-class] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/packaging/boot-jar-manifest-main-class.gradle.kts[tags=main-class] +---- [[packaging-executable-configuring-excluding-devtools]] @@ -126,11 +179,17 @@ By default, Spring Boot's Devtools module, or war. If you want to include Devtools in your archive set the `excludeDevtools` property to `false`: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/packaging/boot-war-include-devtools.gradle[tags=include-devtools] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/packaging/boot-war-include-devtools.gradle.kts[tags=include-devtools] +---- [[packaging-executable-configuring-unpacking]] @@ -145,11 +204,19 @@ specific nested jars to a temporary folder when the executable archive is run. L can be identified as requiring unpacking using Ant-style patterns that match against the absolute path of the source jar file: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/packaging/boot-jar-requires-unpack.gradle[tags=requires-unpack] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/packaging/boot-jar-requires-unpack.gradle.kts[tags=requires-unpack] +---- + + For more control a closure can also be used. The closure is passed a `FileTreeElement` and should return a `boolean` indicating whether or not unpacking is required. @@ -165,28 +232,50 @@ other executable or to be installed as a service. To use this feature, the inclusion of the launch script must be enabled: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/packaging/boot-jar-include-launch-script.gradle[tags=include-launch-script] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/packaging/boot-jar-include-launch-script.gradle.kts[tags=include-launch-script] +---- + + This will add Spring Boot's default launch script to the archive. The default launch script includes several properties with sensible default values. The values can be customized using the `properties` property: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/packaging/boot-jar-launch-script-properties.gradle[tags=launch-script-properties] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/packaging/boot-jar-launch-script-properties.gradle.kts[tags=launch-script-properties] +---- + + If the default launch script does not meet your needs, the `script` property can be used to provide a custom launch script: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/packaging/boot-jar-custom-launch-script.gradle[tags=custom-launch-script] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/packaging/boot-jar-custom-launch-script.gradle.kts[tags=custom-launch-script] +---- [[packaging-executable-configuring-properties-launcher]] @@ -195,7 +284,15 @@ include::../gradle/packaging/boot-jar-custom-launch-script.gradle[tags=custom-la To use the `PropertiesLauncher` to launch an executable jar or war, configure the task's manifest to set the `Main-Class` attribute: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/packaging/boot-war-properties-launcher.gradle[tags=properties-launcher] ---- + +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/packaging/boot-war-properties-launcher.gradle.kts[tags=properties-launcher] +---- + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/publishing.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/publishing.adoc index 6ba51474bd..8219e9145c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/publishing.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/publishing.adoc @@ -12,11 +12,19 @@ default, the `bootArchives` configuration contains the archive produced by the ` or `bootWar` task. The `uploadBootArchives` task can be configured to publish the archive to a Maven repository: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/publishing/maven.gradle[tags=upload] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/publishing/maven.gradle.kts[tags=upload] +---- + + [[publishing-your-application-maven-publish]] === Publishing with the `maven-publish` plugin @@ -25,11 +33,17 @@ method on `MavenPublication`. Pass the task that produces that artifact that you to publish to the `artifact` method. For example, to publish the artifact produced by the default `bootJar` task: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/publishing/maven-publish.gradle[tags=publishing] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/publishing/maven-publish.gradle.kts[tags=publishing] +---- [[publishing-your-application-distribution]] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/running.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/running.adoc index 03fe6865d6..19d0101e55 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/running.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/running.adoc @@ -19,27 +19,49 @@ By default, the main class will be configured automatically by looking for a cla The main class can also be configured explicitly using the task's `main` property: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/running/boot-run-main.gradle[tags=main] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/running/boot-run-main.gradle.kts[tags=main] +---- + + Alternatively, the main class name can be configured project-wide using the `mainClassName` property of the Spring Boot DSL: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/running/spring-boot-dsl-main-class-name.gradle[tags=main-class] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/running/spring-boot-dsl-main-class-name.gradle.kts[tags=main-class] +---- + + If the {application-plugin}[`application` plugin] has been applied, its `mainClassName` project property can be used for the same purpose: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/running/application-plugin-main-class-name.gradle[tags=main-class] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/running/application-plugin-main-class-name.gradle.kts[tags=main-class] +---- [[running-your-application-passing-arguments]] @@ -64,10 +86,18 @@ If devtools has been added to your project it will automatically monitor your application for changes. Alternatively, you can configure `bootRun` such that your application's static resources are loaded from their source location: -[source,groovy,indent=0,subs="verbatim"] +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy ---- include::../gradle/running/boot-run-source-resources.gradle[tags=source-resources] ---- +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/running/boot-run-source-resources.gradle.kts[tags=source-resources] +---- + + This makes them reloadable in the live application which can be helpful at development time. diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-release.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-release.gradle.kts new file mode 100644 index 0000000000..5f006ab6d2 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-release.gradle.kts @@ -0,0 +1,3 @@ +plugins { + id("org.springframework.boot") version "{version}" +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/milestone-settings.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/milestone-settings.gradle new file mode 100644 index 0000000000..bd12480b19 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/milestone-settings.gradle @@ -0,0 +1,14 @@ +pluginManagement { + repositories { + maven { + url 'https://repo.spring.io/libs-milestone' + } + } + resolutionStrategy { + eachPlugin { + if (requested.id.id == 'org.springframework.boot') { + useModule "org.springframework.boot:spring-boot-gradle-plugin:${requested.version}" + } + } + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/milestone-settings.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/milestone-settings.gradle.kts new file mode 100644 index 0000000000..ba66973b5b --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/milestone-settings.gradle.kts @@ -0,0 +1,14 @@ +pluginManagement { + repositories { + maven { + url = uri("https://repo.spring.io/libs-milestone") + } + } + resolutionStrategy { + eachPlugin { + if (requested.id.id == "org.springframework.boot") { + useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") + } + } + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/snapshot-settings.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/snapshot-settings.gradle new file mode 100644 index 0000000000..4fa5e135aa --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/snapshot-settings.gradle @@ -0,0 +1,14 @@ +pluginManagement { + repositories { + maven { + url 'https://repo.spring.io/libs-snapshot' + } + } + resolutionStrategy { + eachPlugin { + if (requested.id.id == 'org.springframework.boot') { + useModule "org.springframework.boot:spring-boot-gradle-plugin:${requested.version}" + } + } + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/snapshot-settings.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/snapshot-settings.gradle.kts new file mode 100644 index 0000000000..13c35d5776 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/snapshot-settings.gradle.kts @@ -0,0 +1,14 @@ +pluginManagement { + repositories { + maven { + url = uri("https://repo.spring.io/libs-snapshot") + } + } + resolutionStrategy { + eachPlugin { + if (requested.id.id == "org.springframework.boot") { + useModule("org.springframework.boot:spring-boot-gradle-plugin:${requested.version}") + } + } + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/typical-plugins.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/typical-plugins.gradle.kts new file mode 100644 index 0000000000..c36c966466 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/typical-plugins.gradle.kts @@ -0,0 +1,15 @@ +// tag::apply[] +plugins { + java + id("org.springframework.boot") version "{version}" +} + +apply(plugin = "io.spring.dependency-management") +// end::apply[] + +task("verify") { + doLast { + project.plugins.getPlugin(JavaPlugin::class) + project.plugins.getPlugin(io.spring.gradle.dependencymanagement.DependencyManagementPlugin::class) + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-additional.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-additional.gradle.kts new file mode 100644 index 0000000000..3010287baa --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-additional.gradle.kts @@ -0,0 +1,18 @@ +plugins { + java + id("org.springframework.boot") version "{version}" +} + +// tag::additional[] +springBoot { + buildInfo { + properties { + additional = mapOf( + "a" to "alpha", + "b" to "bravo" + ) + } + } +} +// end::additional[] + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-basic.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-basic.gradle.kts new file mode 100644 index 0000000000..73741e41c9 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-basic.gradle.kts @@ -0,0 +1,10 @@ +plugins { + java + id("org.springframework.boot") version "{version}" +} + +// tag::build-info[] +springBoot { + buildInfo() +} +// end::build-info[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-custom-values.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-custom-values.gradle.kts new file mode 100644 index 0000000000..eabad8c284 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-custom-values.gradle.kts @@ -0,0 +1,17 @@ +plugins { + java + id("org.springframework.boot") version "{version}" +} + +// tag::custom-values[] +springBoot { + buildInfo { + properties { + artifact = "example-app" + version = "1.2.3" + group = "com.example" + name = "Example application" + } + } +} +// end::custom-values[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/configure-bom-with-plugins.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/configure-bom-with-plugins.gradle.kts new file mode 100644 index 0000000000..ea2b36bbed --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/configure-bom-with-plugins.gradle.kts @@ -0,0 +1,27 @@ +// tag::configure-bom[] +plugins { + java + id("org.springframework.boot") version "{version}" apply false + id("io.spring.dependency-management") version "{dependency-management-plugin-version}" +} + +dependencyManagement { + imports { + mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES) + } +} +// end::configure-bom[] + +dependencyManagement { + resolutionStrategy { + eachDependency { + if (requested.group == "org.springframework.boot") { + useVersion("{version}") + } + } + } +} + +repositories { + mavenLocal() +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/configure-bom.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/configure-bom.gradle index 70bcdb2cb0..a6faa67f75 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/configure-bom.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/configure-bom.gradle @@ -3,13 +3,21 @@ plugins { id 'org.springframework.boot' version '{version}' } +// tag::configure-bom[] apply plugin: 'io.spring.dependency-management' +dependencyManagement { + imports { + mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES + } +} +// end::configure-bom[] + dependencyManagement { resolutionStrategy { eachDependency { if (it.requested.group == 'org.springframework.boot') { - it.useVersion project.bootVersion + it.useVersion '{version}' } } } @@ -18,13 +26,3 @@ dependencyManagement { repositories { mavenLocal() } - -// tag::configure-bom[] -apply plugin: 'io.spring.dependency-management' - -dependencyManagement { - imports { - mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES - } -} -// end::configure-bom[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/configure-bom.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/configure-bom.gradle.kts new file mode 100644 index 0000000000..4f0d989d6e --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/configure-bom.gradle.kts @@ -0,0 +1,30 @@ +import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension + +plugins { + java + id("org.springframework.boot") version "{version}" +} + +// tag::configure-bom[] +apply(plugin = "io.spring.dependency-management") + +the().apply { + imports { + mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES) + } +} +// end::configure-bom[] + +the().apply { + resolutionStrategy { + eachDependency { + if (requested.group == "org.springframework.boot") { + useVersion("{version}") + } + } + } +} + +repositories { + mavenLocal() +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/custom-version.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/custom-version.gradle index f5e022c578..ae022ba67b 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/custom-version.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/custom-version.gradle @@ -8,7 +8,7 @@ dependencyManagement { resolutionStrategy { eachDependency { if (it.requested.group == 'org.springframework.boot') { - it.useVersion project.bootVersion + it.useVersion '{version}' } } } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/custom-version.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/custom-version.gradle.kts new file mode 100644 index 0000000000..01e9dcf0b1 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/custom-version.gradle.kts @@ -0,0 +1,31 @@ +import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension + +plugins { + id("org.springframework.boot") version "{version}" +} + +apply(plugin = "io.spring.dependency-management") + +the().apply { + resolutionStrategy { + eachDependency { + if (requested.group == "org.springframework.boot") { + useVersion("{version}") + } + } + } +} + +// tag::custom-version[] +extra["slf4j.version"] = "1.7.20" +// end::custom-version[] + +repositories { + mavenLocal() +} + +task("slf4jVersion") { + doLast { + println(project.the().managedVersions["org.slf4j:slf4j-api"]) + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/depend-on-plugin-release.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/depend-on-plugin-release.gradle.kts new file mode 100644 index 0000000000..b8acfc1f5a --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/depend-on-plugin-release.gradle.kts @@ -0,0 +1,3 @@ +plugins { + id("org.springframework.boot") version "{version}" apply false +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/dependencies.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/dependencies.gradle.kts new file mode 100644 index 0000000000..fb31765267 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/dependencies.gradle.kts @@ -0,0 +1,13 @@ +plugins { + java + id("org.springframework.boot") version "{version}" +} + +apply(plugin = "io.spring.dependency-management") + +// tag::dependencies[] +dependencies { + implementation("org.springframework.boot:spring-boot-starter-web") + implementation("org.springframework.boot:spring-boot-starter-data-jpa") +} +// end::dependencies[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/application-plugin-main-class.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/application-plugin-main-class.gradle.kts new file mode 100644 index 0000000000..d5d442769e --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/application-plugin-main-class.gradle.kts @@ -0,0 +1,11 @@ +plugins { + java + application + id("org.springframework.boot") version "{version}" +} + +// tag::main-class[] +application { + mainClassName = "com.example.ExampleApplication" +} +// end::main-class[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-and-jar.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-and-jar.gradle.kts new file mode 100644 index 0000000000..50291ab488 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-and-jar.gradle.kts @@ -0,0 +1,22 @@ +import org.springframework.boot.gradle.tasks.bundling.BootJar + +plugins { + java + id("org.springframework.boot") version "{version}" +} + +// tag::enable-jar[] +tasks.getByName("jar") { + enabled = true +} +// end::enable-jar[] + +// tag::classifier[] +tasks.getByName("bootJar") { + classifier = "boot" +} +// end::classifier[] + +tasks.getByName("bootJar") { + mainClassName = "com.example.Application" +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-custom-launch-script.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-custom-launch-script.gradle.kts new file mode 100644 index 0000000000..9e20e7fa15 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-custom-launch-script.gradle.kts @@ -0,0 +1,18 @@ +import org.springframework.boot.gradle.tasks.bundling.BootJar + +plugins { + java + id("org.springframework.boot") version "{version}" +} + +tasks.getByName("bootJar") { + mainClassName = "com.example.ExampleApplication" +} + +// tag::custom-launch-script[] +tasks.getByName("bootJar") { + launchScript { + script = file("src/custom.script") + } +} +// end::custom-launch-script[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-include-launch-script.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-include-launch-script.gradle.kts new file mode 100644 index 0000000000..4a7306e089 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-include-launch-script.gradle.kts @@ -0,0 +1,16 @@ +import org.springframework.boot.gradle.tasks.bundling.BootJar + +plugins { + java + id("org.springframework.boot") version "{version}" +} + +tasks.getByName("bootJar") { + mainClassName = "com.example.ExampleApplication" +} + +// tag::include-launch-script[] +tasks.getByName("bootJar") { + launchScript() +} +// end::include-launch-script[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-launch-script-properties.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-launch-script-properties.gradle.kts new file mode 100644 index 0000000000..a389cf44df --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-launch-script-properties.gradle.kts @@ -0,0 +1,18 @@ +import org.springframework.boot.gradle.tasks.bundling.BootJar + +plugins { + java + id("org.springframework.boot") version "{version}" +} + +tasks.getByName("bootJar") { + mainClassName = "com.example.ExampleApplication" +} + +// tag::launch-script-properties[] +tasks.getByName("bootJar") { + launchScript { + properties(mapOf("logFilename" to "example-app.log")) + } +} +// end::launch-script-properties[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-main-class.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-main-class.gradle.kts new file mode 100644 index 0000000000..306d8774bd --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-main-class.gradle.kts @@ -0,0 +1,12 @@ +import org.springframework.boot.gradle.tasks.bundling.BootJar + +plugins { + java + id("org.springframework.boot") version "{version}" +} + +// tag::main-class[] +tasks.getByName("bootJar") { + mainClassName = "com.example.ExampleApplication" +} +// end::main-class[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-manifest-main-class.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-manifest-main-class.gradle.kts new file mode 100644 index 0000000000..b0f7040046 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-manifest-main-class.gradle.kts @@ -0,0 +1,14 @@ +import org.springframework.boot.gradle.tasks.bundling.BootJar + +plugins { + java + id("org.springframework.boot") version "{version}" +} + +// tag::main-class[] +tasks.getByName("bootJar") { + manifest { + attributes("Start-Class" to "com.example.ExampleApplication") + } +} +// end::main-class[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-requires-unpack.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-requires-unpack.gradle.kts new file mode 100644 index 0000000000..32e238e010 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-requires-unpack.gradle.kts @@ -0,0 +1,24 @@ +import org.springframework.boot.gradle.tasks.bundling.BootJar + +plugins { + java + id("org.springframework.boot") version "{version}" +} + +repositories { + mavenCentral() +} + +dependencies { + runtimeOnly("org.jruby:jruby-complete:1.7.25") +} + +tasks.getByName("bootJar") { + mainClassName = "com.example.ExampleApplication" +} + +// tag::requires-unpack[] +tasks.getByName("bootJar") { + requiresUnpack("**/jruby-complete-*.jar") +} +// end::requires-unpack[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-include-devtools.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-include-devtools.gradle.kts new file mode 100644 index 0000000000..aab3f6ed6e --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-include-devtools.gradle.kts @@ -0,0 +1,17 @@ +import org.springframework.boot.gradle.tasks.bundling.BootWar + +plugins { + war + id("org.springframework.boot") version "{version}" +} + +tasks.getByName("bootWar") { + mainClassName = "com.example.ExampleApplication" + classpath(file("spring-boot-devtools-1.2.3.RELEASE.jar")) +} + +// tag::include-devtools[] +tasks.getByName("bootWar") { + isExcludeDevtools = false +} +// end::include-devtools[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-properties-launcher.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-properties-launcher.gradle.kts new file mode 100644 index 0000000000..e2f78bbb65 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-properties-launcher.gradle.kts @@ -0,0 +1,18 @@ +import org.springframework.boot.gradle.tasks.bundling.BootWar + +plugins { + war + id("org.springframework.boot") version "{version}" +} + +tasks.getByName("bootWar") { + mainClassName = "com.example.ExampleApplication" +} + +// tag::properties-launcher[] +tasks.getByName("bootWar") { + manifest { + attributes("Main-Class" to "org.springframework.boot.loader.PropertiesLauncher") + } +} +// end::properties-launcher[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/spring-boot-dsl-main-class.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/spring-boot-dsl-main-class.gradle.kts new file mode 100644 index 0000000000..c07ab49cfa --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/spring-boot-dsl-main-class.gradle.kts @@ -0,0 +1,10 @@ +plugins { + war + id("org.springframework.boot") version "{version}" +} + +// tag::main-class[] +springBoot { + mainClassName = "com.example.ExampleApplication" +} +// end::main-class[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/war-container-dependency.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/war-container-dependency.gradle.kts new file mode 100644 index 0000000000..92c4cb080c --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/war-container-dependency.gradle.kts @@ -0,0 +1,13 @@ +plugins { + war + id("org.springframework.boot") version "{version}" +} + +apply(plugin = "io.spring.dependency-management") + +// tag::dependencies[] +dependencies { + implementation("org.springframework.boot:spring-boot-starter-web") + providedRuntime("org.springframework.boot:spring-boot-starter-tomcat") +} +// end::dependencies[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven-publish.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven-publish.gradle.kts new file mode 100644 index 0000000000..b07e1b9084 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven-publish.gradle.kts @@ -0,0 +1,27 @@ +plugins { + java + `maven-publish` + id("org.springframework.boot") version "{version}" +} + +// tag::publishing[] +publishing { + publications { + create("bootJava") { + artifact(tasks.getByName("bootJar")) + } + } + repositories { + maven { + url = uri("https://repo.example.com") + } + } +} +// end::publishing[] + +task("publishingConfiguration") { + doLast { + println(publishing.publications["bootJava"]) + println(publishing.repositories.getByName("maven").url) + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven.gradle.kts new file mode 100644 index 0000000000..35caea2043 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven.gradle.kts @@ -0,0 +1,26 @@ +plugins { + java + maven + id("org.springframework.boot") version "{version}" +} + +// tag::upload[] +tasks.getByName("uploadBootArchives") { + repositories.withGroovyBuilder { + "mavenDeployer" { + "repository"("url" to "https://repo.example.com") + } + } +} +// end::upload[] + +val url = tasks.getByName("uploadBootArchives") + .repositories + .withGroovyBuilder { getProperty("mavenDeployer") } + .withGroovyBuilder { getProperty("repository") } + .withGroovyBuilder { getProperty("url") } +task("deployerRepository") { + doLast { + println(url) + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/application-plugin-main-class-name.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/application-plugin-main-class-name.gradle.kts new file mode 100644 index 0000000000..6cf2ddcc62 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/application-plugin-main-class-name.gradle.kts @@ -0,0 +1,19 @@ +import org.springframework.boot.gradle.tasks.run.BootRun + +plugins { + java + application + id("org.springframework.boot") version "{version}" +} + +// tag::main-class[] +application { + mainClassName = "com.example.ExampleApplication" +} +// end::main-class[] + +task("configuredMainClass") { + doLast { + println(tasks.getByName("bootRun").main) + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-main.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-main.gradle.kts new file mode 100644 index 0000000000..380ef98f5f --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-main.gradle.kts @@ -0,0 +1,18 @@ +import org.springframework.boot.gradle.tasks.run.BootRun + +plugins { + java + id("org.springframework.boot") version "{version}" +} + +// tag::main[] +tasks.getByName("bootRun") { + main = "com.example.ExampleApplication" +} +// end::main[] + +task("configuredMainClass") { + doLast { + println(tasks.getByName("bootRun").main) + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-source-resources.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-source-resources.gradle.kts new file mode 100644 index 0000000000..9e8f5ec4bf --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-source-resources.gradle.kts @@ -0,0 +1,18 @@ +import org.springframework.boot.gradle.tasks.run.BootRun + +plugins { + java + id("org.springframework.boot") version "{version}" +} + +// tag::source-resources[] +tasks.getByName("bootRun") { + sourceResources(sourceSets["main"]) +} +// end::source-resources[] + +task("configuredClasspath") { + doLast { + println(tasks.getByName("bootRun").classpath.files) + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/spring-boot-dsl-main-class-name.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/spring-boot-dsl-main-class-name.gradle.kts new file mode 100644 index 0000000000..9c0e2371ad --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/spring-boot-dsl-main-class-name.gradle.kts @@ -0,0 +1,19 @@ +import org.springframework.boot.gradle.tasks.run.BootRun + +plugins { + java + application + id("org.springframework.boot") version "{version}" +} + +// tag::main-class[] +springBoot { + mainClassName = "com.example.ExampleApplication" +} +// end::main-class[] + +task("configuredMainClass") { + doLast { + println(tasks.getByName("bootRun").main) + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/GettingStartedDocumentationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/GettingStartedDocumentationTests.java index 26d3ad6195..8117963301 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/GettingStartedDocumentationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/GettingStartedDocumentationTests.java @@ -18,25 +18,29 @@ package org.springframework.boot.gradle.docs; import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.gradle.junit.GradleMultiDslSuite; import org.springframework.boot.gradle.testkit.GradleBuild; /** * Tests for the getting started documentation. * * @author Andy Wilkinson + * @author Jean-Baptiste Nizet */ +@RunWith(GradleMultiDslSuite.class) public class GettingStartedDocumentationTests { @Rule - public GradleBuild gradleBuild = new GradleBuild(); + public GradleBuild gradleBuild; // NOTE: We can't run any `apply-plugin` tests because during a release the // jar won't be there @Test public void typicalPluginsAppliesExceptedPlugins() { - this.gradleBuild.script("src/main/gradle/getting-started/typical-plugins.gradle") + this.gradleBuild.script("src/main/gradle/getting-started/typical-plugins") .build("verify"); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/IntegratingWithActuatorDocumentationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/IntegratingWithActuatorDocumentationTests.java index 03b1bcdc63..6c8887ccb2 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/IntegratingWithActuatorDocumentationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/IntegratingWithActuatorDocumentationTests.java @@ -23,7 +23,9 @@ import java.util.Properties; import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.gradle.junit.GradleMultiDslSuite; import org.springframework.boot.gradle.testkit.GradleBuild; import static org.assertj.core.api.Assertions.assertThat; @@ -32,16 +34,18 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for the generating build info documentation. * * @author Andy Wilkinson + * @author Jean-Baptiste Nizet */ +@RunWith(GradleMultiDslSuite.class) public class IntegratingWithActuatorDocumentationTests { @Rule - public GradleBuild gradleBuild = new GradleBuild(); + public GradleBuild gradleBuild; @Test public void basicBuildInfo() throws IOException { - this.gradleBuild.script( - "src/main/gradle/integrating-with-actuator/build-info-basic.gradle") + this.gradleBuild + .script("src/main/gradle/integrating-with-actuator/build-info-basic") .build("bootBuildInfo"); assertThat(new File(this.gradleBuild.getProjectDir(), "build/resources/main/META-INF/build-info.properties")).isFile(); @@ -50,7 +54,7 @@ public class IntegratingWithActuatorDocumentationTests { @Test public void buildInfoCustomValues() throws IOException { this.gradleBuild.script( - "src/main/gradle/integrating-with-actuator/build-info-custom-values.gradle") + "src/main/gradle/integrating-with-actuator/build-info-custom-values") .build("bootBuildInfo"); File file = new File(this.gradleBuild.getProjectDir(), "build/resources/main/META-INF/build-info.properties"); @@ -64,8 +68,8 @@ public class IntegratingWithActuatorDocumentationTests { @Test public void buildInfoAdditional() throws IOException { - this.gradleBuild.script( - "src/main/gradle/integrating-with-actuator/build-info-additional.gradle") + this.gradleBuild + .script("src/main/gradle/integrating-with-actuator/build-info-additional") .build("bootBuildInfo"); File file = new File(this.gradleBuild.getProjectDir(), "build/resources/main/META-INF/build-info.properties"); 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 3394219aa9..ab93a81607 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 @@ -16,9 +16,13 @@ package org.springframework.boot.gradle.docs; +import org.junit.Assume; import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.gradle.junit.GradleMultiDslSuite; +import org.springframework.boot.gradle.testkit.Dsl; import org.springframework.boot.gradle.testkit.GradleBuild; import static org.assertj.core.api.Assertions.assertThat; @@ -27,30 +31,40 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for the managing dependencies documentation. * * @author Andy Wilkinson + * @author Jean-Baptiste Nizet */ +@RunWith(GradleMultiDslSuite.class) public class ManagingDependenciesDocumentationTests { @Rule - public GradleBuild gradleBuild = new GradleBuild(); + public GradleBuild gradleBuild; @Test public void dependenciesExampleEvaluatesSuccessfully() { - this.gradleBuild - .script("src/main/gradle/managing-dependencies/dependencies.gradle") + this.gradleBuild.script("src/main/gradle/managing-dependencies/dependencies") .build(); } @Test public void customManagedVersions() { assertThat(this.gradleBuild - .script("src/main/gradle/managing-dependencies/custom-version.gradle") + .script("src/main/gradle/managing-dependencies/custom-version") .build("slf4jVersion").getOutput()).contains("1.7.20"); } @Test public void dependencyManagementInIsolation() { assertThat(this.gradleBuild - .script("src/main/gradle/managing-dependencies/configure-bom.gradle") + .script("src/main/gradle/managing-dependencies/configure-bom") + .build("dependencyManagement").getOutput()) + .contains("org.springframework.boot:spring-boot-starter "); + } + + @Test + public void dependencyManagementInIsolationWithPluginsBlock() { + Assume.assumeTrue(this.gradleBuild.getDsl() == Dsl.KOTLIN); + assertThat(this.gradleBuild.script( + "src/main/gradle/managing-dependencies/configure-bom-with-plugins") .build("dependencyManagement").getOutput()) .contains("org.springframework.boot:spring-boot-starter "); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PackagingDocumentationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PackagingDocumentationTests.java index e380bf789e..5a14062d24 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PackagingDocumentationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PackagingDocumentationTests.java @@ -25,7 +25,10 @@ import java.util.jar.JarFile; import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.gradle.junit.GradleMultiDslSuite; +import org.springframework.boot.gradle.testkit.Dsl; import org.springframework.boot.gradle.testkit.GradleBuild; import org.springframework.util.FileCopyUtils; @@ -35,22 +38,25 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for the packaging documentation. * * @author Andy Wilkinson + * @author Jean-Baptiste Nizet */ +@RunWith(GradleMultiDslSuite.class) public class PackagingDocumentationTests { @Rule - public GradleBuild gradleBuild = new GradleBuild(); + public GradleBuild gradleBuild; + + public Dsl dsl; @Test public void warContainerDependencyEvaluatesSuccessfully() { - this.gradleBuild - .script("src/main/gradle/packaging/war-container-dependency.gradle") + this.gradleBuild.script("src/main/gradle/packaging/war-container-dependency") .build(); } @Test public void bootJarMainClass() throws IOException { - this.gradleBuild.script("src/main/gradle/packaging/boot-jar-main-class.gradle") + this.gradleBuild.script("src/main/gradle/packaging/boot-jar-main-class") .build("bootJar"); File file = new File(this.gradleBuild.getProjectDir(), "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar"); @@ -63,8 +69,7 @@ public class PackagingDocumentationTests { @Test public void bootJarManifestMainClass() throws IOException { - this.gradleBuild - .script("src/main/gradle/packaging/boot-jar-manifest-main-class.gradle") + this.gradleBuild.script("src/main/gradle/packaging/boot-jar-manifest-main-class") .build("bootJar"); File file = new File(this.gradleBuild.getProjectDir(), "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar"); @@ -77,8 +82,7 @@ public class PackagingDocumentationTests { @Test public void applicationPluginMainClass() throws IOException { - this.gradleBuild - .script("src/main/gradle/packaging/application-plugin-main-class.gradle") + this.gradleBuild.script("src/main/gradle/packaging/application-plugin-main-class") .build("bootJar"); File file = new File(this.gradleBuild.getProjectDir(), "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar"); @@ -91,8 +95,7 @@ public class PackagingDocumentationTests { @Test public void springBootDslMainClass() throws IOException { - this.gradleBuild - .script("src/main/gradle/packaging/spring-boot-dsl-main-class.gradle") + this.gradleBuild.script("src/main/gradle/packaging/spring-boot-dsl-main-class") .build("bootJar"); File file = new File(this.gradleBuild.getProjectDir(), "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar"); @@ -107,8 +110,7 @@ public class PackagingDocumentationTests { public void bootWarIncludeDevtools() throws IOException { new File(this.gradleBuild.getProjectDir(), "spring-boot-devtools-1.2.3.RELEASE.jar").createNewFile(); - this.gradleBuild - .script("src/main/gradle/packaging/boot-war-include-devtools.gradle") + this.gradleBuild.script("src/main/gradle/packaging/boot-war-include-devtools") .build("bootWar"); File file = new File(this.gradleBuild.getProjectDir(), "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".war"); @@ -121,8 +123,7 @@ public class PackagingDocumentationTests { @Test public void bootJarRequiresUnpack() throws IOException { - this.gradleBuild - .script("src/main/gradle/packaging/boot-jar-requires-unpack.gradle") + this.gradleBuild.script("src/main/gradle/packaging/boot-jar-requires-unpack") .build("bootJar"); File file = new File(this.gradleBuild.getProjectDir(), "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar"); @@ -137,7 +138,7 @@ public class PackagingDocumentationTests { @Test public void bootJarIncludeLaunchScript() throws IOException { this.gradleBuild - .script("src/main/gradle/packaging/boot-jar-include-launch-script.gradle") + .script("src/main/gradle/packaging/boot-jar-include-launch-script") .build("bootJar"); File file = new File(this.gradleBuild.getProjectDir(), "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar"); @@ -148,8 +149,8 @@ public class PackagingDocumentationTests { @Test public void bootJarLaunchScriptProperties() throws IOException { - this.gradleBuild.script( - "src/main/gradle/packaging/boot-jar-launch-script-properties.gradle") + this.gradleBuild + .script("src/main/gradle/packaging/boot-jar-launch-script-properties") .build("bootJar"); File file = new File(this.gradleBuild.getProjectDir(), "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar"); @@ -164,8 +165,7 @@ public class PackagingDocumentationTests { "src/custom.script"); customScriptFile.getParentFile().mkdirs(); FileCopyUtils.copy("custom", new FileWriter(customScriptFile)); - this.gradleBuild - .script("src/main/gradle/packaging/boot-jar-custom-launch-script.gradle") + this.gradleBuild.script("src/main/gradle/packaging/boot-jar-custom-launch-script") .build("bootJar"); File file = new File(this.gradleBuild.getProjectDir(), "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar"); @@ -175,8 +175,7 @@ public class PackagingDocumentationTests { @Test public void bootWarPropertiesLauncher() throws IOException { - this.gradleBuild - .script("src/main/gradle/packaging/boot-war-properties-launcher.gradle") + this.gradleBuild.script("src/main/gradle/packaging/boot-war-properties-launcher") .build("bootWar"); File file = new File(this.gradleBuild.getProjectDir(), "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".war"); @@ -188,8 +187,8 @@ public class PackagingDocumentationTests { } @Test - public void bootJarAndJar() throws IOException { - this.gradleBuild.script("src/main/gradle/packaging/boot-jar-and-jar.gradle") + public void bootJarAndJar() { + this.gradleBuild.script("src/main/gradle/packaging/boot-jar-and-jar") .build("assemble"); File jar = new File(this.gradleBuild.getProjectDir(), "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar"); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PublishingDocumentationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PublishingDocumentationTests.java index b57a0ab60e..7a796d4c67 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PublishingDocumentationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PublishingDocumentationTests.java @@ -20,7 +20,9 @@ import java.io.IOException; import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.gradle.junit.GradleMultiDslSuite; import org.springframework.boot.gradle.testkit.GradleBuild; import static org.assertj.core.api.Assertions.assertThat; @@ -29,26 +31,27 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for the publishing documentation. * * @author Andy Wilkinson + * @author Jean-Baptiste Nizet */ +@RunWith(GradleMultiDslSuite.class) public class PublishingDocumentationTests { @Rule - public GradleBuild gradleBuild = new GradleBuild(); + public GradleBuild gradleBuild; @Test public void mavenUpload() throws IOException { - assertThat(this.gradleBuild.script("src/main/gradle/publishing/maven.gradle") + assertThat(this.gradleBuild.script("src/main/gradle/publishing/maven") .build("deployerRepository").getOutput()) .contains("https://repo.example.com"); } @Test public void mavenPublish() throws IOException { - assertThat( - this.gradleBuild.script("src/main/gradle/publishing/maven-publish.gradle") - .build("publishingConfiguration").getOutput()) - .contains("MavenPublication") - .contains("https://repo.example.com"); + assertThat(this.gradleBuild.script("src/main/gradle/publishing/maven-publish") + .build("publishingConfiguration").getOutput()) + .contains("MavenPublication") + .contains("https://repo.example.com"); } } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/RunningDocumentationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/RunningDocumentationTests.java index 32a0155b47..cfb543ccf9 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/RunningDocumentationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/RunningDocumentationTests.java @@ -21,7 +21,9 @@ import java.io.IOException; import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.gradle.junit.GradleMultiDslSuite; import org.springframework.boot.gradle.testkit.GradleBuild; import static org.assertj.core.api.Assertions.assertThat; @@ -30,23 +32,25 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for the documentation about running a Spring Boot application. * * @author Andy Wilkinson + * @author Jean-Baptiste Nizet */ +@RunWith(GradleMultiDslSuite.class) public class RunningDocumentationTests { @Rule - public GradleBuild gradleBuild = new GradleBuild(); + public GradleBuild gradleBuild; @Test public void bootRunMain() throws IOException { - assertThat(this.gradleBuild.script("src/main/gradle/running/boot-run-main.gradle") + assertThat(this.gradleBuild.script("src/main/gradle/running/boot-run-main") .build("configuredMainClass").getOutput()) .contains("com.example.ExampleApplication"); } @Test - public void applicationPluginMainClassName() throws IOException { - assertThat(this.gradleBuild.script( - "src/main/gradle/running/application-plugin-main-class-name.gradle") + public void applicationPluginMainClassName() { + assertThat(this.gradleBuild + .script("src/main/gradle/running/application-plugin-main-class-name") .build("configuredMainClass").getOutput()) .contains("com.example.ExampleApplication"); } @@ -54,7 +58,7 @@ public class RunningDocumentationTests { @Test public void springBootDslMainClassName() throws IOException { assertThat(this.gradleBuild - .script("src/main/gradle/running/spring-boot-dsl-main-class-name.gradle") + .script("src/main/gradle/running/spring-boot-dsl-main-class-name") .build("configuredMainClass").getOutput()) .contains("com.example.ExampleApplication"); } @@ -62,7 +66,7 @@ public class RunningDocumentationTests { @Test public void bootRunSourceResources() throws IOException { assertThat(this.gradleBuild - .script("src/main/gradle/running/boot-run-source-resources.gradle") + .script("src/main/gradle/running/boot-run-source-resources") .build("configuredClasspath").getOutput()) .contains(new File("src/main/resources").getPath()); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/junit/GradleMultiDslSuite.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/junit/GradleMultiDslSuite.java new file mode 100644 index 0000000000..dc0e3e6ffc --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/junit/GradleMultiDslSuite.java @@ -0,0 +1,86 @@ +/* + * Copyright 2012-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.gradle.junit; + +import java.util.ArrayList; +import java.util.List; + +import org.gradle.api.Rule; +import org.junit.runner.Runner; +import org.junit.runners.BlockJUnit4ClassRunner; +import org.junit.runners.Suite; +import org.junit.runners.model.FrameworkMethod; +import org.junit.runners.model.InitializationError; + +import org.springframework.boot.gradle.testkit.Dsl; +import org.springframework.boot.gradle.testkit.GradleBuild; + +/** + * Custom {@link Suite} that runs tests against the Groovy and the Kotlin DSLs. Test + * classes using the suite must have a public {@link GradleBuild} field named + * {@code gradleBuild} and annotated with {@link Rule}. + * + * @author Jean-Baptiste Nizet + * @author Andy Wilkinson + */ +public final class GradleMultiDslSuite extends Suite { + + public GradleMultiDslSuite(Class clazz) throws InitializationError { + super(clazz, createRunners(clazz)); + } + + private static List createRunners(Class clazz) throws InitializationError { + List runners = new ArrayList<>(); + runners.add(new GradleDslClassRunner(clazz, new GradleBuild(Dsl.GROOVY))); + runners.add(new GradleDslClassRunner(clazz, new GradleBuild(Dsl.KOTLIN))); + return runners; + } + + private static final class GradleDslClassRunner extends BlockJUnit4ClassRunner { + + private final GradleBuild gradleBuild; + + private GradleDslClassRunner(Class klass, GradleBuild gradleBuild) + throws InitializationError { + super(klass); + this.gradleBuild = gradleBuild; + } + + @Override + protected Object createTest() throws Exception { + Object test = super.createTest(); + configureTest(test); + return test; + } + + private void configureTest(Object test) throws Exception { + test.getClass().getField("gradleBuild").set(test, this.gradleBuild); + } + + @Override + protected String getName() { + return this.gradleBuild.getDsl().getName() + " DSL"; + } + + @Override + protected String testName(FrameworkMethod method) { + return method.getName() + " [" + getName() + "]"; + } + + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/Dsl.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/Dsl.java new file mode 100644 index 0000000000..974f308389 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/Dsl.java @@ -0,0 +1,48 @@ +/* + * Copyright 2012-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.boot.gradle.testkit; + +/** + * The DSLs supported by Gradle and demonstrated in the documentation samples + */ +public enum Dsl { + + GROOVY("Groovy", ".gradle"), KOTLIN("Kotlin", ".gradle.kts"); + + private final String name; + + private final String extension; + + Dsl(String name, String extension) { + this.name = name; + this.extension = extension; + } + + /** + * Gets the user-friendly name of the DSL + */ + public String getName() { + return this.name; + } + + /** + * Gets the file extension of build scripts (starting with a dot) + */ + String getExtension() { + return this.extension; + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java index 0d7996c424..1622672eec 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java @@ -26,6 +26,7 @@ import java.util.Arrays; import java.util.List; import java.util.regex.Pattern; +import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathFactory; @@ -43,6 +44,9 @@ import org.junit.rules.TemporaryFolder; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.springframework.asm.ClassVisitor; @@ -61,12 +65,26 @@ public class GradleBuild implements TestRule { private final TemporaryFolder temp = new TemporaryFolder(); + private final Dsl dsl; + private File projectDir; private String script; private String gradleVersion; + public GradleBuild() { + this(Dsl.GROOVY); + } + + public GradleBuild(Dsl dsl) { + this.dsl = dsl; + } + + public Dsl getDsl() { + return this.dsl; + } + @Override public Statement apply(Statement base, Description description) { URL scriptUrl = findDefaultScript(description); @@ -99,7 +117,8 @@ public class GradleBuild implements TestRule { private URL getScriptForTestMethod(Description description) { String name = description.getTestClass().getSimpleName() + "-" - + removeGradleVersion(description.getMethodName()) + ".gradle"; + + removeGradleVersion(description.getMethodName()) + + this.dsl.getExtension(); return description.getTestClass().getResource(name); } @@ -108,7 +127,7 @@ public class GradleBuild implements TestRule { } private URL getScriptForTestClass(Class testClass) { - return testClass.getResource(testClass.getSimpleName() + ".gradle"); + return testClass.getResource(testClass.getSimpleName() + this.dsl.getExtension()); } private void before() throws IOException { @@ -138,7 +157,8 @@ public class GradleBuild implements TestRule { } public GradleBuild script(String script) { - this.script = script; + this.script = script.endsWith(this.dsl.getExtension()) ? script + : script + this.dsl.getExtension(); return this; } @@ -162,15 +182,23 @@ public class GradleBuild implements TestRule { public GradleRunner prepareRunner(String... arguments) throws IOException { String scriptContent = FileCopyUtils.copyToString(new FileReader(this.script)) - .replace("{version}", getBootVersion()); - FileCopyUtils.copy(scriptContent, - new FileWriter(new File(this.projectDir, "build.gradle"))); + .replace("{version}", getBootVersion()) + .replace("{dependency-management-plugin-version}", + getDependencyManagementPluginVersion()); + FileCopyUtils.copy(scriptContent, new FileWriter( + new File(this.projectDir, "build" + this.dsl.getExtension()))); GradleRunner gradleRunner = GradleRunner.create().withProjectDir(this.projectDir) - .withDebug(true).withPluginClasspath(pluginClasspath()); - + .withPluginClasspath(pluginClasspath()); + if (this.dsl != Dsl.KOTLIN) { + // see https://github.com/gradle/gradle/issues/6862 + gradleRunner.withDebug(true); + } if (this.gradleVersion != null) { gradleRunner.withGradleVersion(this.gradleVersion); } + else if (this.dsl == Dsl.KOTLIN) { + gradleRunner.withGradleVersion("4.10.2"); + } List allArguments = new ArrayList<>(); allArguments.add("-PbootVersion=" + getBootVersion()); allArguments.add("--stacktrace"); @@ -201,13 +229,34 @@ public class GradleBuild implements TestRule { + "/text()"); } + private static String getDependencyManagementPluginVersion() { + try (FileReader pomReader = new FileReader(".flattened-pom.xml")) { + Document pom = DocumentBuilderFactory.newInstance().newDocumentBuilder() + .parse(new InputSource(pomReader)); + NodeList dependencyElements = pom.getElementsByTagName("dependency"); + for (int i = 0; i < dependencyElements.getLength(); i++) { + Element dependency = (Element) dependencyElements.item(i); + if (dependency.getElementsByTagName("artifactId").item(0).getTextContent() + .equals("dependency-management-plugin")) { + return dependency.getElementsByTagName("version").item(0) + .getTextContent(); + } + } + throw new IllegalStateException( + "dependency management plugin version not found"); + } + catch (Exception ex) { + throw new IllegalStateException( + "Failed to find dependency management plugin version", ex); + } + } + private static String evaluateExpression(String expression) { - try { + try (FileReader pomReader = new FileReader(".flattened-pom.xml")) { XPathFactory xPathFactory = XPathFactory.newInstance(); XPath xpath = xPathFactory.newXPath(); XPathExpression expr = xpath.compile(expression); - String version = expr - .evaluate(new InputSource(new FileReader(".flattened-pom.xml"))); + String version = expr.evaluate(new InputSource(pomReader)); return version; } catch (Exception ex) {