diff --git a/spring-boot-docs/pom.xml b/spring-boot-docs/pom.xml
index 7c96c172e9..33788d4b04 100644
--- a/spring-boot-docs/pom.xml
+++ b/spring-boot-docs/pom.xml
@@ -853,6 +853,15 @@
META-INF/**
+
+ org.springframework.boot
+ spring-boot-gradle-plugin
+ ${project.version}
+ docs
+ zip
+ ${project.build.directory}/contents/gradle-plugin
+ META-INF/**
+
diff --git a/spring-boot-docs/src/main/asciidoc/build-tool-plugins.adoc b/spring-boot-docs/src/main/asciidoc/build-tool-plugins.adoc
index 1f914771ba..d0de570135 100644
--- a/spring-boot-docs/src/main/asciidoc/build-tool-plugins.adoc
+++ b/spring-boot-docs/src/main/asciidoc/build-tool-plugins.adoc
@@ -164,516 +164,11 @@ Advanced configuration options and examples are available in the
[[build-tool-plugins-gradle-plugin]]
== Spring Boot Gradle plugin
-The Spring Boot Gradle Plugin provides Spring Boot support in Gradle, allowing you to
-package executable jar or war archives, run Spring Boot applications and use the
-dependency management provided by `spring-boot-dependencies`.
-
-
-
-[[build-tool-plugins-including-the-gradle-plugin]]
-=== Including the plugin
-ifeval::["{spring-boot-repo}" == "release"]
-To use the Spring Boot Gradle Plugin configure it using the `plugins` block:
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- plugins {
- id 'org.springframework.boot' version '{spring-boot-version}'
- }
-----
-endif::[]
-ifeval::["{spring-boot-repo}" != "release"]
-To use the Spring Boot Gradle Plugin simply include a `buildscript` dependency and apply
-the `spring-boot` plugin:
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- buildscript {
- repositories {
- maven { url 'http://repo.spring.io/snapshot' }
- maven { url 'http://repo.spring.io/milestone' }
- }
- dependencies {
- classpath 'org.springframework.boot:spring-boot-gradle-plugin:{spring-boot-version}''
- }
- }
- apply plugin: 'org.springframework.boot'
-----
-endif::[]
-
-
-
-[[build-tool-plugins-gradle-dependency-management]]
-=== Gradle dependency management
-The `spring-boot` plugin automatically applies the
-{dependency-management-plugin}/[Dependency Management Plugin] and configures it to import
-the `spring-boot-starter-parent` bom. This provides a similar dependency management
-experience to the one that is enjoyed by Maven users. For example, it allows you to omit
-version numbers when declaring dependencies that are managed in the bom. To make use of
-this functionality, simply declare dependencies in the usual way, but leave the version
-number empty:
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- dependencies {
- compile("org.springframework.boot:spring-boot-starter-web")
- compile("org.thymeleaf:thymeleaf-spring5")
- compile("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect")
- }
-----
-
-NOTE: The version of the `spring-boot` gradle plugin that you declare determines the
-version of the `spring-boot-starter-parent` bom that is imported (this ensures that builds
-are always repeatable). You should always set the version of the `spring-boot` gradle
-plugin to the actual Spring Boot version that you wish to use. Details of the versions
-that are provided can be found in the <>.
-
-To learn more about the capabilities of the Dependency Management Plugin, please refer to
-its {dependency-management-plugin-documentation}[documentation].
-
-
-
-[[build-tool-plugins-gradle-packaging]]
-=== Packaging executable jar and war files
-Once the `spring-boot` plugin has been applied to your project it will automatically
-attempt to rewrite archives to make them executable using the
-<>. You
-should configure your project to build a jar or war (as appropriate) in the usual way.
-
-The main class that you want to launch can either be specified using a configuration
-option, or by adding a `Main-Class` attribute to the manifest. If you don't specify a
-main class the plugin will search for a class with a
-`public static void main(String[] args)` method.
-
-TIP: Check <> for a full list of
-configuration options.
-
-To build and run a project artifact, you can type the following:
-
-[indent=0]
-----
- $ gradle build
- $ java -jar build/libs/mymodule-0.0.1-SNAPSHOT.jar
-----
-
-To build a war file that is both executable and deployable into an external container,
-you need to mark the embedded container dependencies as belonging to the war plugin's
-`providedRuntime` configuration, e.g.:
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- ...
- apply plugin: 'war'
-
- war {
- baseName = 'myapp'
- version = '0.5.0'
- }
-
- repositories {
- jcenter()
- maven { url "http://repo.spring.io/libs-snapshot" }
- }
-
- dependencies {
- compile("org.springframework.boot:spring-boot-starter-web")
- providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
- ...
- }
-----
-
-TIP: See the "`<>`" section for more details on
-how to create a deployable war file.
-
-
-
-[[build-tool-plugins-gradle-running-applications]]
-=== Running a project in-place
-To run a project in place without building a jar first you can use the "`bootRun`" task:
-
-[indent=0]
-----
- $ gradle bootRun
-----
-
-If <> has been added to your project
-it will automatically monitor your application for changes. Alternatively, you can also
-run the application so that your static classpath resources (i.e. in `src/main/resources`
-by default) are reloadable in the live application, which can be helpful at development
-time.
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- bootRun {
- addResources = true
- }
-----
-
-Making static classpath resources reloadable means that `bootRun` does not use the output
-of the `processResources` task, i.e., when invoked using `bootRun`, your application will
-use the resources in their unprocessed form.
-
-
-
-[[build-tool-plugins-gradle-global-configuration]]
-=== Spring Boot plugin configuration
-The gradle plugin automatically extends your build script DSL with a `springBoot` element
-for global configuration of the Boot plugin. Set the appropriate properties as you would
-with any other Gradle extension (see below for a list of configuration options):
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- springBoot {
- backupSource = false
- }
-----
-
-
-
-[[build-tool-plugins-gradle-repackage-configuration]]
-=== Repackage configuration
-The plugin adds a `bootRepackage` task which you can also configure directly, e.g.:
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- bootRepackage {
- mainClass = 'demo.Application'
- }
-----
-
-The following configuration options are available:
-
-[cols="2,4"]
-|===
-|Name |Description
-
-|`enabled`
-|Boolean flag to switch the repackager off (sometimes useful if you
-want the other Boot features but not this one)
-
-|`mainClass`
-|The main class that should be run. If not specified, and you have applied the application
- plugin, the `mainClassName` project property will be used. If the application plugin has
- not been applied or no `mainClassName` has been specified, the archive will be searched
- for a suitable class. "Suitable" means a unique class with a well-formed `main()` method
- (if more than one is found the build will fail). If you have applied the application
- plugin, the main class can also be specified via its "run" task (`main` property) and/or
- its "startScripts" task (`mainClassName` property) as an alternative to using the
- "springBoot" configuration.
-
-|`classifier`
-|A file name segment (before the extension) to add to the archive, so that the original is
- preserved in its original location. Defaults to `null` in which case the archive is
- repackaged in place. The default is convenient for many purposes, but if you want to use
- the original jar as a dependency in another project you must use a classifier to define
- the executable archive.
-
-|`withJarTask`
-|The name or value of the `Jar` task (defaults to all tasks of type `Jar`) which is used
- to locate the archive to repackage.
-
-|`customConfiguration`
-|The name of the custom configuration which is used to populate the nested lib directory
- (without specifying this you get all compile and runtime dependencies).
-
-|`executable`
-|Boolean flag to indicate if jar files are fully executable on Unix like operating
- systems. Defaults to `false`.
-
-|`embeddedLaunchScript`
-|The embedded launch script to prepend to the front of the jar if it is fully executable.
- If not specified the 'Spring Boot' default script will be used.
-
-|`embeddedLaunchScriptProperties`
-|Additional properties that to be expanded in the launch script. The default script
- supports a `mode` property which can contain the values `auto`, `service` or `run`.
-
-|`excludeDevtools`
-|Boolean flag to indicate if the devtools jar should be excluded from the repackaged
-archives. Defaults to `true`.
-|===
-
-
-
-[[build-tool-plugins-gradle-repackage-custom-configuration]]
-=== Repackage with custom Gradle configuration
-Sometimes it may be more appropriate to not package default dependencies resolved from
-`compile`, `runtime` and `provided` scopes. If the created executable jar file
-is intended to be run as it is, you need to have all dependencies nested inside it;
-however, if the plan is to explode a jar file and run the main class manually, you may already
-have some of the libraries available via `CLASSPATH`. This is a situation where
-you can repackage your jar with a different set of dependencies.
-
-Using a custom
-configuration will automatically disable dependency resolving from
-`compile`, `runtime` and `provided` scopes. Custom configuration can be either
-defined globally (inside the `springBoot` section) or per task.
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- task clientJar(type: Jar) {
- appendix = 'client'
- from sourceSets.main.output
- exclude('**/*Something*')
- }
-
- task clientBoot(type: BootRepackage, dependsOn: clientJar) {
- withJarTask = clientJar
- customConfiguration = "mycustomconfiguration"
- }
-----
-
-In above example, we created a new `clientJar` Jar task to package a customized
-file set from your compiled sources. Then we created a new `clientBoot`
-BootRepackage task and instructed it to work with only `clientJar` task and
-`mycustomconfiguration`.
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- configurations {
- mycustomconfiguration.exclude group: 'log4j'
- }
-
- dependencies {
- mycustomconfiguration configurations.runtime
- }
-----
-
-The configuration that we are referring to in `BootRepackage` is a normal
-{gradle-dsl}/org.gradle.api.artifacts.Configuration.html[Gradle
-configuration]. In the above example we created a new configuration named
-`mycustomconfiguration` instructing it to derive from a `runtime` and exclude the `log4j`
-group. If the `clientBoot` task is executed, the repackaged boot jar will have all
-dependencies from `runtime` but no `log4j` jars.
-
-
-
-[[build-tool-plugins-gradle-configuration-options]]
-==== Configuration options
-The following configuration options are available:
-
-[cols="2,4"]
-|===
-|Name |Description
-
-|`mainClass`
-|The main class that should be run by the executable archive.
-
-|`providedConfiguration`
-|The name of the provided configuration (defaults to `providedRuntime`).
-
-|`backupSource`
-|If the original source archive should be backed-up before being repackaged (defaults
- to `true`).
-
-|`customConfiguration`
-|The name of the custom configuration.
-
-|`layout`
-|The type of archive, corresponding to how the dependencies are laid out inside
- (defaults to a guess based on the archive type). See
- <>.
-
-|`layoutFactory`
-|A layout factory that can be used if a custom layout is required. Alternative layouts
-can be provided by 3rd parties. Layout factories are only used when `layout` is not
-specified.
-
-|`requiresUnpack`
-|A list of dependencies (in the form "`groupId:artifactId`" that must be unpacked from
- fat jars in order to run. Items are still packaged into the fat jar, but they will be
- automatically unpacked when it runs.
-|===
-
-
-
-[[build-tool-plugins-gradle-configuration-layouts]]
-==== Available layouts
-
-The `layout` attribute configures the format of the archive and whether the bootstrap
-loader should be included or not. The following layouts are available:
-
-[cols="2,4,1"]
-|===
-|Name |Description |Executable
-
-|`JAR`
-|Regular executable
- <>.
-|Yes
-
-|`WAR`
-|Executable
- <>.
- `provided` dependencies are placed in `WEB-INF/lib-provided` to avoid any clash when
- the `war` is deployed in a servlet container.
-|Yes
-
-|`ZIP` (alias to `DIR`)
-|Similar to `JAR` layout, using
- <>.
-| Yes
-
-|`MODULE`
-|Bundle dependencies (excluding those with `provided` scope) and project resources.
-|No
-
-|`NONE`
-|Bundle all dependencies and project resources.
-|No
-|===
-
-
-
-[[build-tool-plugins-gradle-configuration-custom-repackager]]
-==== Using a custom layout
-If you have custom requirements for how to arrange the dependencies and loader classes
-inside the repackaged jar, you can use a custom layout. Any library which defines one
-or more `LayoutFactory` implementations can be added to the build script dependencies
-and then the layout factory becomes available in the `springBoot` configuration.
-For example:
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
-buildscript {
- repositories {
- mavenCentral()
- }
- dependencies {
- classpath("org.springframework.boot:spring-boot-gradle-plugin:{spring-boot-version}")
- classpath("com.example:custom-layout:1.0.0")
- }
-}
-
-springBoot {
- layoutFactory = new com.example.CustomLayoutFactory()
-}
-----
-
-NOTE: If there is only one custom `LayoutFactory` on the build classpath and it is
-listed in `META-INF/spring.factories` then it is unnecessary to explicitly set it in the
-`springBoot` configuration. Layout factories are only used when no explicit `layout` is
-specified.
-
-
-
-[[build-tool-plugins-understanding-the-gradle-plugin]]
-=== Understanding how the Gradle plugin works
-When `spring-boot` is applied to your Gradle project a default task named `bootRepackage`
-is created automatically. The `bootRepackage` task depends on Gradle `assemble` task, and
-when executed, it tries to find all jar artifacts whose qualifier is empty (i.e. tests and
-sources jars are automatically skipped).
-
-Due to the fact that `bootRepackage` finds 'all' created jar artifacts, the order of
-Gradle task execution is important. Most projects only create a single jar file, so
-usually this is not an issue; however, if you are planning to create a more complex
-project setup, with custom `Jar` and `BootRepackage` tasks, there are few tweaks to
-consider.
-
-If you are 'just' creating custom jar files from your project you can simply disable
-default `jar` and `bootRepackage` tasks:
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- jar.enabled = false
- bootRepackage.enabled = false
-----
-
-Another option is to instruct the default `bootRepackage` task to only work with a
-default `jar` task.
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- bootRepackage.withJarTask = jar
-----
-
-If you have a default project setup where the main jar file is created and repackaged,
-'and' you still want to create additional custom jars, you can combine your custom
-repackage tasks together and use `dependsOn` so that the `bootJars` task will run after
-the default `bootRepackage` task is executed:
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- task bootJars
- bootJars.dependsOn = [clientBoot1,clientBoot2,clientBoot3]
- build.dependsOn(bootJars)
-----
-
-All the above tweaks are usually used to avoid situations where an already created boot
-jar is repackaged again. Repackaging an existing boot jar will not break anything, but
-you may find that it includes unnecessary dependencies.
-
-
-
-[[build-tool-plugins-gradle-publishing-artifacts-to-a-maven-repository]]
-=== Publishing artifacts to a Maven repository using Gradle
-If you are <> and you want to publish artifacts to a Maven repository
-you will need to configure the Maven publication with details of Spring Boot's
-dependency management. This can be achieved by configuring it to publish poms that
-inherit from `spring-boot-starter-parent` or that import dependency management from
-`spring-boot-dependencies`. The exact details of this configuration depend on how you're
-using Gradle and how you're trying to publish the artifacts.
-
-
-
-[[build-tool-plugins-gradle-publishing-artifacts-to-a-maven-repository-inherit]]
-==== Configuring Gradle to produce a pom that inherits dependency management
-The following is an example of configuring Gradle to generate a pom that inherits
-from `spring-boot-starter-parent`. Please refer to the
-{gradle-user-guide}/userguide.html[Gradle User Guide] for further information.
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- uploadArchives {
- repositories {
- mavenDeployer {
- pom {
- project {
- parent {
- groupId "org.springframework.boot"
- artifactId "spring-boot-starter-parent"
- version "{spring-boot-version}"
- }
- }
- }
- }
- }
- }
-----
-
-
-
-[[build-tool-plugins-gradle-publishing-artifacts-to-a-maven-repository-import]]
-==== Configuring Gradle to produce a pom that imports dependency management
-The following is an example of configuring Gradle to generate a pom that imports
-the dependency management provided by `spring-boot-dependencies`. Please refer to the
-http://www.gradle.org/docs/current/userguide/userguide.html[Gradle User Guide] for
-further information.
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- uploadArchives {
- repositories {
- mavenDeployer {
- pom {
- project {
- dependencyManagement {
- dependencies {
- dependency {
- groupId "org.springframework.boot"
- artifactId "spring-boot-dependencies"
- version "{spring-boot-version}"
- type "pom"
- scope "import"
- }
- }
- }
- }
- }
- }
- }
- }
-----
+The {spring-boot-gradle-plugin}[Spring Boot Gradle Plugin] provides Spring Boot support
+in Gradle, allowing you to package executable jar or war archives, run Spring Boot
+applications and use the dependency management provided by `spring-boot-dependencies`.
+It requires Gradle 3.4 or later. Please refer to the {spring-boot-gradle-plugin}[plugin's
+documentation] to learn more.
diff --git a/spring-boot-docs/src/main/asciidoc/howto.adoc b/spring-boot-docs/src/main/asciidoc/howto.adoc
index e4fea6f590..368919a213 100644
--- a/spring-boot-docs/src/main/asciidoc/howto.adoc
+++ b/spring-boot-docs/src/main/asciidoc/howto.adoc
@@ -827,12 +827,12 @@ Example in Gradle:
[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
----
configurations {
- compile.exclude module: "spring-boot-starter-tomcat"
+ compile.exclude module: 'spring-boot-starter-tomcat'
}
dependencies {
- compile("org.springframework.boot:spring-boot-starter-web:{spring-boot-version}")
- compile("org.springframework.boot:spring-boot-starter-jetty:{spring-boot-version}")
+ compile 'org.springframework.boot:spring-boot-starter-web'
+ compile 'org.springframework.boot:spring-boot-starter-jetty'
// ...
}
----
@@ -881,12 +881,12 @@ Example in Gradle:
[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
----
configurations {
- compile.exclude module: "spring-boot-starter-tomcat"
+ compile.exclude module: 'spring-boot-starter-tomcat'
}
dependencies {
- compile("org.springframework.boot:spring-boot-starter-web:{spring-boot-version}")
- compile("org.springframework.boot:spring-boot-starter-undertow:{spring-boot-version}")
+ compile 'org.springframework.boot:spring-boot-starter-web'
+ compile 'org.springframework.boot:spring-boot-starter-undertow'
// ...
}
----
@@ -2355,9 +2355,11 @@ To configure IntelliJ IDEA correctly you can use the `idea` Gradle plugin:
[source,groovy,indent=0,subs="verbatim,attributes"]
----
buildscript {
- repositories { jcenter() }
+ repositories {
+ jcenter()
+ }
dependencies {
- classpath "org.springframework.boot:spring-boot-gradle-plugin:{spring-boot-version}"
+ classpath 'org.springframework.boot:spring-boot-gradle-plugin:{spring-boot-version}'
classpath 'org.springframework:springloaded:1.2.6.RELEASE'
}
}
@@ -2424,7 +2426,7 @@ And to do the same with Gradle:
[source,groovy,indent=0,subs="verbatim,attributes"]
----
- springBoot {
+ springBoot {
buildInfo()
}
----
@@ -2502,16 +2504,7 @@ the artifact yourself instead of overriding the property.
WARNING: Each Spring Boot release is designed and tested against a specific set of
third-party dependencies. Overriding versions may cause compatibility issues.
-To override dependency versions in Gradle, you can specify a version as shown below:
-[source,groovy,indent=0]
-----
- ext['slf4j.version'] = '1.7.5'
-----
-
-For additional information, please refer to the
-https://github.com/spring-gradle-plugins/dependency-management-plugin[Gradle Dependency
-Management Plugin documentation].
[[howto-create-an-executable-jar-with-maven]]
=== Create an executable JAR with Maven
@@ -2593,15 +2586,6 @@ To configure a classifier of `exec` in Maven, the following configuration can be
----
-And when using Gradle, the following configuration can be used:
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- bootRepackage {
- classifier = 'exec'
- }
-----
-
[[howto-extract-specific-libraries-when-an-executable-jar-runs]]
@@ -2637,15 +2621,6 @@ you would add the following configuration:
----
-And to do that same with Gradle:
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- springBoot {
- requiresUnpack = ['org.jruby:jruby-complete']
- }
-----
-
[[howto-create-a-nonexecutable-jar]]
@@ -2689,29 +2664,6 @@ jar must be the main artifact and you can add a classified jar for the library:
----
-In Gradle you can create a new JAR archive with standard task DSL features, and then have
-the `bootRepackage` task depend on that one using its `withJarTask` property:
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- jar {
- baseName = 'spring-boot-sample-profile'
- version = '0.0.0'
- excludes = ['**/application.yml']
- }
-
- task('execJar', type:Jar, dependsOn: 'jar') {
- baseName = 'spring-boot-sample-profile'
- version = '0.0.0'
- classifier = 'exec'
- from sourceSets.main.output
- }
-
- bootRepackage {
- withJarTask = tasks['execJar']
- }
-----
-
[[howto-remote-debug-maven-run]]
@@ -2723,34 +2675,6 @@ Check {spring-boot-maven-plugin-site}/examples/run-debug.html[this example] for
-[[howto-remote-debug-gradle-run]]
-=== Remote debug a Spring Boot application started with Gradle
-To attach a remote debugger to a Spring Boot application started with Gradle you can use
-the `jvmArgs` property of `bootRun` task or `--debug-jvm` command line option.
-
-`build.gradle`:
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
- bootRun {
- jvmArgs "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"
- }
-----
-
-
-Command line:
-
-[indent=0]
-----
- $ gradle bootRun --debug-jvm
-----
-
-
-Check {gradle-userguide}/application_plugin.html[Gradle Application Plugin] for more
-details.
-
-
-
[[howto-build-an-executable-archive-with-ant]]
=== Build an executable archive from Ant without using spring-boot-antlib
To build with Ant you need to grab dependencies, compile and then create a jar or war
@@ -2894,10 +2818,9 @@ And if you're using Gradle:
}
----
-NOTE: If you are using a version of Gradle that supports compile only dependencies (2.12
-or later), you should continue to use `providedRuntime`. Among other limitations,
-`compileOnly` dependencies are not on the test classpath so any web-based integration
-tests will fail.
+NOTE: `providedRuntime` is prefered to Gradle's `compileOnly` configuration as, among other
+limitations, `compileOnly` dependencies are not on the test classpath so any web-based
+integration tests will fail.
If you're using the <>,
marking the embedded servlet container dependency as provided will produce an executable war
diff --git a/spring-boot-docs/src/main/asciidoc/index.adoc b/spring-boot-docs/src/main/asciidoc/index.adoc
index de0438ccfb..d79d7e60b5 100644
--- a/spring-boot-docs/src/main/asciidoc/index.adoc
+++ b/spring-boot-docs/src/main/asciidoc/index.adoc
@@ -34,7 +34,8 @@ Phillip Webb; Dave Syer; Josh Long; Stéphane Nicoll; Rob Winch; Andy Wilkinson;
:dc-spring-boot-test-autoconfigure: {dc-root}/org/springframework/boot/test/autoconfigure
:dependency-management-plugin: https://github.com/spring-gradle-plugins/dependency-management-plugin
:dependency-management-plugin-documentation: {dependency-management-plugin}/blob/master/README.md
-:spring-boot-maven-plugin-site: http://docs.spring.io/spring-boot/docs/{spring-boot-docs-version}/maven-plugin
+:spring-boot-maven-plugin-site: http://docs.spring.io/spring-boot/docs/{spring-boot-docs-version}/maven-plugin/
+:spring-boot-gradle-plugin: http://docs.spring.io/spring-boot/docs/{spring-boot-docs-version}/gradle-plugin/
:spring-reference: http://docs.spring.io/spring/docs/{spring-docs-version}/spring-framework-reference/htmlsingle
:spring-security-reference: http://docs.spring.io/spring-security/site/docs/{spring-security-docs-version}/reference/htmlsingle
:spring-security-oauth2-reference: http://projects.spring.io/spring-security-oauth/docs/oauth2.html
@@ -50,8 +51,7 @@ Phillip Webb; Dave Syer; Josh Long; Stéphane Nicoll; Rob Winch; Andy Wilkinson;
:propdeps-plugin: https://github.com/spring-projects/gradle-plugins/tree/master/propdeps-plugin
:ant-manual: http://ant.apache.org/manual
:code-examples: ../java/org/springframework/boot
-:gradle-user-guide: https://docs.gradle.org/2.14.1/userguide
-:gradle-dsl: https://docs.gradle.org/2.14.1/dsl
+:gradle-user-guide: https://docs.gradle.org/3.4.1/userguide
// ======================================================================================
include::documentation-overview.adoc[]
diff --git a/spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc b/spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc
index 8b8ea14149..7ac1ddb557 100644
--- a/spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc
+++ b/spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc
@@ -41,8 +41,8 @@ feel that's necessary.
The curated list contains all the spring modules that you can use with Spring Boot as
well as a refined list of third party libraries. The list is available as a standard
<>
-and additional dedicated support for <> and
-<> are available as well.
+that can be used with both <> and
+{spring-boot-gradle-plugin}[Gradle].
WARNING: Each release of Spring Boot is associated with a base version of the Spring
Framework so we **highly** recommend you to not specify its version on your own.
@@ -194,70 +194,8 @@ the parent.
[[using-boot-gradle]]
=== Gradle
-Gradle users can directly import '`starters`' in their `dependencies` section. Unlike
-Maven, there is no "`super parent`" to import to share some configuration.
-
-[source,groovy,indent=0,subs="attributes"]
-----
- repositories {
-ifeval::["{spring-boot-repo}" != "release"]
- maven { url "http://repo.spring.io/snapshot" }
- maven { url "http://repo.spring.io/milestone" }
-endif::[]
-ifeval::["{spring-boot-repo}" == "release"]
- jcenter()
-endif::[]
- }
-
- dependencies {
- compile("org.springframework.boot:spring-boot-starter-web:{spring-boot-version}")
- }
-----
-
-The <> is also available and provides tasks to create executable
-jars and run projects from source. It also provides
-<> that, among
-other capabilities, allows you to omit the version number for any dependencies that are
-managed by Spring Boot:
-
-[source,groovy,indent=0,subs="attributes"]
-----
-ifeval::["{spring-boot-repo}" == "release"]
- plugins {
- id 'org.springframework.boot' version '{spring-boot-version}'
- id 'java'
- }
-endif::[]
-ifeval::["{spring-boot-repo}" != "release"]
- buildscript {
- repositories {
- jcenter()
- maven { url 'http://repo.spring.io/snapshot' }
- maven { url 'http://repo.spring.io/milestone' }
- }
- dependencies {
- classpath 'org.springframework.boot:spring-boot-gradle-plugin:{spring-boot-version}'
- }
- }
-
- apply plugin: 'java'
- apply plugin: 'org.springframework.boot'
-endif::[]
-
- repositories {
- jcenter()
-ifeval::["{spring-boot-repo}" != "release"]
- maven { url 'http://repo.spring.io/snapshot' }
- maven { url 'http://repo.spring.io/milestone' }
-endif::[]
- }
-
- dependencies {
- compile("org.springframework.boot:spring-boot-starter-web")
- testCompile("org.springframework.boot:spring-boot-starter-test")
- }
-----
+To learn about using Spring Boot with Gradle, please refer to the
+{spring-boot-gradle-plugin}[documentation for Spring Boot's Gradle plugin].
@@ -704,8 +642,8 @@ You might also want to use the useful operating system environment variable:
[[using-boot-running-with-the-gradle-plugin]]
=== Using the Gradle plugin
The Spring Boot Gradle plugin also includes a `bootRun` task which can be used to run
-your application in an exploded form. The `bootRun` task is added whenever you import
-the `spring-boot-gradle-plugin`:
+your application in an exploded form. The `bootRun` task is added whenever you apply the
+the `org.springframework.boot` and `java` plugins:
[indent=0,subs="attributes"]
----
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/build.gradle b/spring-boot-tools/spring-boot-gradle-plugin/build.gradle
index 01b42fef76..cc3fcc4975 100644
--- a/spring-boot-tools/spring-boot-gradle-plugin/build.gradle
+++ b/spring-boot-tools/spring-boot-gradle-plugin/build.gradle
@@ -46,7 +46,6 @@ jar {
}
}
-
eclipseJdt {
inputFile = rootProject.file('../../eclipse/org.eclipse.jdt.core.prefs')
doLast {
@@ -56,6 +55,18 @@ eclipseJdt {
}
}
+javadoc {
+ options {
+ author()
+ stylesheetFile = file('src/main/javadoc/spring-javadoc.css')
+ links = [
+ 'http://docs.oracle.com/javase/8/docs/api/',
+ 'https://docs.gradle.org/current/javadoc/'
+ ]
+ }
+ title = "${project.description} $version API"
+}
+
task sourcesJar(type: Jar) {
classifier = 'sources'
from sourceSets.main.allSource
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/pom.xml b/spring-boot-tools/spring-boot-gradle-plugin/pom.xml
index e289a5b380..a9e432ece7 100644
--- a/spring-boot-tools/spring-boot-gradle-plugin/pom.xml
+++ b/spring-boot-tools/spring-boot-gradle-plugin/pom.xml
@@ -58,6 +58,7 @@
clean
build
-Pversion=${project.version}
+ -Pdescription=${project.description}
@@ -112,5 +113,138 @@
gradlew.bat
+
+ full
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+
+
+ ant-contrib
+ ant-contrib
+ 1.0b3
+
+
+ ant
+ ant
+
+
+
+
+ org.apache.ant
+ ant-nodeps
+ 1.8.1
+
+
+ org.tigris.antelope
+ antelopetasks
+ 3.2.10
+
+
+
+
+ set-up-maven-properties
+ prepare-package
+
+ run
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ package-docs-zip
+ package
+
+ run
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.asciidoctor
+ asciidoctor-maven-plugin
+ 1.5.3
+
+
+ generate-html-documentation
+ prepare-package
+
+ process-asciidoc
+
+
+ html
+
+
+
+ generate-pdf-documentation
+ prepare-package
+
+ process-asciidoc
+
+
+ pdf
+
+
+
+
+
+ ${version-type}
+ ${project.version}
+
+
+
+
+ org.asciidoctor
+ asciidoctorj-pdf
+ 1.5.0-alpha.11
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+
+
+ attach-zip
+
+ attach-artifact
+
+
+
+
+ ${project.build.directory}/${project.artifactId}-${project.version}-docs.zip
+ zip
+ docs
+
+
+
+
+
+
+
+
+
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/getting-started.adoc b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/getting-started.adoc
new file mode 100644
index 0000000000..0ec83436f4
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/getting-started.adoc
@@ -0,0 +1,43 @@
+[[getting-started]]
+== Getting started
+
+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"]
+----
+include::../gradle/getting-started/apply-plugin-release.gradle[]
+----
+endif::[]
+ifeval::["{version-type}" == "MILESTONE"]
+[source,groovy,indent=0,subs="verbatim,attributes"]
+----
+include::../gradle/getting-started/apply-plugin-milestone.gradle[]
+----
+endif::[]
+ifeval::["{version-type}" == "SNAPSHOT"]
+[source,groovy,indent=0,subs="verbatim,attributes"]
+----
+include::../gradle/getting-started/apply-plugin-snapshot.gradle[]
+----
+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_plugin.html[`java`], or {kotlin-plugin}[`org.jetbrains.kotlin.jvm`]
+plugin and the {dependency-management-plugin}[`io.spring.dependency-management`] plugin as
+a minimum. For example:
+
+[source,groovy,indent=0,subs="verbatim,attributes"]
+----
+include::../gradle/getting-started/typical-plugins.gradle[tags=apply]
+----
+
+To learn more about how the Spring Boot plugin behaves when other plugins are applied
+please see the section on <>.
\ No newline at end of file
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/index.adoc b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/index.adoc
new file mode 100644
index 0000000000..17645f4e9f
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/index.adoc
@@ -0,0 +1,48 @@
+= Spring Boot Gradle Plugin Reference Guide
+Andy Wilkinson
+:doctype: book
+:toc: left
+:toclevels: 4
+:source-highlighter: prettify
+:numbered:
+:icons: font
+:hide-uri-scheme:
+:dependency-management-plugin: https://github.com/spring-gradle-plugins/dependency-management-plugin
+:dependency-management-plugin-documentation: {dependency-management-plugin}/blob/master/README.md
+:gradle-userguide: http://www.gradle.org/docs/current/userguide
+:gradle-dsl: https://docs.gradle.org/current/dsl
+:application-plugin: {gradle-userguide}/application_plugin.html
+:groovy-plugin: {gradle-userguide}/groovy_plugin.html
+:java-plugin: {gradle-userguide}/java_plugin.html
+:war-plugin: {gradle-userguide}/war_plugin.html
+:maven-plugin: {gradle-userguide}/maven_plugin.html
+:maven-publish-plugin: {gradle-userguide}/maven_publish_plugin.html
+:software-component: {gradle-userguide}/software_model_extend.html
+:kotlin-plugin: https://kotlinlang.org/docs/reference/using-gradle.html
+:spring-boot-docs: https://docs.spring.io/spring-boot/{version}
+:api-documentation: {spring-boot-docs}/gradle-plugin/api
+:spring-boot-reference: {spring-boot-docs}/reference/htmlsingle
+:build-info-javadoc: {api-documentation}/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.html
+:boot-jar-javadoc: {api-documentation}/org/springframework/boot/gradle/tasks/bundling/BootJar.html
+:boot-war-javadoc: {api-documentation}/org/springframework/boot/gradle/tasks/bundling/BootWar.html
+:boot-run-javadoc: {api-documentation}/org/springframework/boot/gradle/tasks/run/BootRun.html
+:github-code: https://github.com/spring-projects/spring-boot/tree/{github-tag}
+
+
+
+[[introduction]]
+== Introduction
+
+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 3.4 or later.
+
+In addition to this user guide, {api-documentation}[API documentation] is also available.
+
+include::getting-started.adoc[]
+include::managing-dependencies.adoc[]
+include::packaging.adoc[]
+include::running.adoc[]
+include::integrating-with-actuator.adoc[]
+include::reacting.adoc[]
\ No newline at end of file
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/integrating-with-actuator.adoc b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/integrating-with-actuator.adoc
new file mode 100644
index 0000000000..0460273bbc
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/integrating-with-actuator.adoc
@@ -0,0 +1,55 @@
+[[integrating-with-actuator]]
+== Integrating with Actuator
+
+
+[[integrating-with-actuator-build-info]]
+=== Generating build information
+
+Spring Boot Actuator's `info` endpoint automatically publishes information about your
+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"]
+----
+include::../gradle/integrating-with-actuator/build-info-basic.gradle[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 desination
+directory will be `META-INF` in the output directory of the main source set's resources
+(typically `build/resources/main`).
+
+By default, the generated build information is derived from the project:
+
+|===
+| Property | Default value
+
+| `build.artifact`
+| The base name of the `bootJar` or `bootWar` task, or `unspecified` if no such task
+ exists
+
+| `build.group`
+| The group of the project
+
+| `build.name`
+| The name of the project
+
+| `build.version`
+| The version of the project
+
+|===
+
+The properties can be customized using the DSL:
+
+[source,groovy,indent=0,subs="verbatim"]
+----
+include::../gradle/integrating-with-actuator/build-info-custom-values.gradle[tags=custom-values]
+----
+
+Additional properties can also be added to the build information:
+
+[source,groovy,indent=0,subs="verbatim"]
+----
+include::../gradle/integrating-with-actuator/build-info-additional.gradle[tags=additional]
+----
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/managing-dependencies.adoc b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/managing-dependencies.adoc
new file mode 100644
index 0000000000..31981561b3
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/managing-dependencies.adoc
@@ -0,0 +1,46 @@
+[[managing-dependencies]]
+== Managing dependencies
+
+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. To make use of this functionality, simply
+declare dependencies in the usual way but omit the version number:
+
+[source,groovy,indent=0,subs="verbatim"]
+----
+include::../gradle/managing-dependencies/dependencies.gradle[tags=dependencies]
+----
+
+
+
+[[managing-dependencies-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. Please refer to the {github-code}/spring-boot-dependencies/pom.xml[bom]
+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"]
+----
+include::../gradle/managing-dependencies/custom-version.gradle[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-learning-more]]
+=== Learning more
+
+To learn more about the capabilities of the dependency management plugin, please refer to
+its {dependency-management-plugin-documentation}[documentation].
\ No newline at end of file
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/packaging.adoc b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/packaging.adoc
new file mode 100644
index 0000000000..686f20a4ea
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/packaging.adoc
@@ -0,0 +1,167 @@
+[[packaging-executable]]
+== Packaging executable archives
+
+The plugin can create executable archives (jar files and war files) that contain all of
+an application's dependencies and can then be run with `java -jar`.
+
+
+
+[[packaging-executable-jars]]
+=== Packaging executable jars
+
+Executable jars can be built using the `bootJar` task. The task is automatically created
+when the `java` plugin is applied and is an instance of {boot-jar-javadoc}[`BootJar`].
+
+
+
+[[packaging-executable-wars]]
+=== Packaging executable wars
+
+Executable wars can be built using the `bootWar` task. The task is automatically created
+when the `war` plugin is applied and is an instance of {boot-war-javadoc}[`BootWar`].
+
+
+
+[[packaging-executable-wars-deployable]]
+==== Packaging executable and deployable wars
+
+A war file can be packaged such that it can be executed using `java -jar` and deployed
+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"]
+----
+include::../gradle/packaging/war-container-dependency.gradle[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.
+
+NOTE: `providedRuntime` is prefered to Gradle's `compileOnly` configuration as, among
+other limitations, `compileOnly` dependencies are not on the test classpath so any
+web-based integration tests will fail.
+
+
+
+[[packaging-executable-configuring]]
+=== Configuring executable archive packaging
+
+The {boot-jar-javadoc}[`BootJar`] and {boot-war-javadoc}[`BootWar`] tasks are subclasses
+of Gradle's `Jar` and `War` tasks respectively. As a result, all of the standard
+configuration options that are available when packaging a jar or war are also available
+when packaging an executable jar or war. A number of configuration options that are
+specific to executable jars and wars are also provided.
+
+
+[[packaging-executable-configuring-main-class]]
+==== Configuring the main class
+
+By default, the executable archive's main class will be configured automatically by
+looking for a class with a `public static void main(String[])` method in directories on
+the task's classpath.
+
+The main class can also be configured explicity using the task's `mainClass` property:
+
+[source,groovy,indent=0,subs="verbatim"]
+----
+include::../gradle/packaging/boot-jar-main-class.gradle[tags=main-class]
+----
+
+Alternatively, if the {application-plugin}[`application` plugin] has been applied
+its `mainClassName` project property can be used:
+
+[source,groovy,indent=0,subs="verbatim"]
+----
+include::../gradle/packaging/application-plugin-main-class.gradle[tags=main-class]
+----
+
+Lastly, the `Start-Class` attribute can be configured on the task's manifest:
+
+[source,groovy,indent=0,subs="verbatim"]
+----
+include::../gradle/packaging/boot-jar-manifest-main-class.gradle[tags=main-class]
+----
+
+
+
+[[packaging-executable-configuring-excluding-devtools]]
+==== Excluding Devtools
+
+By default, Spring Boot's Devtools module,
+`org.springframework.boot:spring-boot-devtools`, will be excluded from an executable jar
+or war. If you want to include Devtools in your archive set the `excludeDevtools`
+property to `true`:
+
+[source,groovy,indent=0,subs="verbatim"]
+----
+include::../gradle/packaging/boot-war-include-devtools.gradle[tags=include-devtools]
+----
+
+
+
+[[packaging-executable-configuring-unpacking]]
+==== Configuring libraries that require unpacking
+
+Most libraries can be used directly when nested in an executable archive, however certain
+libraries can have problems. For example, JRuby includes its own nested jar support which
+assumes that `jruby-complete.jar` is always directly available on the file system.
+
+To deal with any problematic libraries, an executable archive can be configured to unpack
+specific nested jars to a temporary folder when the executable archive is run. Libraries
+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"]
+----
+include::../gradle/packaging/boot-jar-requires-unpack.gradle[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.
+
+
+
+[[packaging-executable-configuring-launch-script]]
+==== Making an archive fully executable
+
+Spring Boot provides support for fully executable archives. An archive is made fully
+executable by prepending a shell script that knows how to launch the application. On
+Unix-like platforms, this launch script allows the archive to be run directly like any
+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"]
+----
+include::../gradle/packaging/boot-jar-include-launch-script.gradle[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"]
+----
+include::../gradle/packaging/boot-jar-launch-script-properties.gradle[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"]
+----
+include::../gradle/packaging/boot-jar-custom-launch-script.gradle[tags=custom-launch-script]
+----
+
+
+
+[[packaging-executable-configuring-properties-launcher]]
+==== Using the `PropertiesLauncher`
+
+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"]
+----
+include::../gradle/packaging/boot-war-properties-launcher.gradle[tags=properties-launcher]
+----
\ No newline at end of file
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/publishing.adoc b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/publishing.adoc
new file mode 100644
index 0000000000..69be4ed6ce
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/publishing.adoc
@@ -0,0 +1,43 @@
+[[publishing-your-application]]
+== Publishing your application
+
+
+
+[[publishing-your-application-maven]]
+=== Publishing with the `maven` plugin
+
+When the {maven-plugin}[`maven` plugin] is applied, an `Upload` task for the
+`bootArchives` configuration named `uploadBootArchives` is automatically created. By
+default, the `bootArchives` configuration contains the archive produced by the `bootJar`
+or `bootWar` task. The `uploadBootArchives` task can be configured to publish the archive
+to a Maven repository:
+
+[source,groovy,indent=0,subs="verbatim"]
+----
+include::../gradle/publishing/maven.gradle[tags=upload]
+----
+
+[[publishing-your-application-maven-publish]]
+=== Publishing with the `maven-publish` plugin
+
+When the {java-plugin}[`java` plugin] is applied Spring Boot automatically creates a
+{software-component}[software component] named `bootJava`. Similarly, when the `war`
+plugin is applied, a software component named `bootWeb` is created. `bootJava` contains
+the archive produced by the `bootJar` task and `bootWeb` contains the archive provided by
+the `bootWar` task. The components can be used with the
+{maven-publish-plugin}[`maven-publish` plugin] to publish the archive, for example:
+
+[source,groovy,indent=0,subs="verbatim"]
+----
+include::../gradle/publishing/maven-publish.gradle[tags=publishing]
+----
+
+
+
+[[publishing-your-application-distrubution]]
+=== Distributing with the `application` plugin
+
+When the {application-plugin}[`application` plugin] is applied a distribution named
+`boot` is created. This distribution contains the archive produced by the `bootJar` or
+`bootWar` task and scripts to launch it on Unix-like platforms and Windows. Zip and tar
+distributions can be built by the `bootDistZip` and `bootDistTar` tasks respectively.
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/reacting.adoc b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/reacting.adoc
new file mode 100644
index 0000000000..4c5fa9a8c1
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/reacting.adoc
@@ -0,0 +1,78 @@
+[[reacting-to-other-plugins]]
+== Reacting to other plugins
+
+When another plugin is applied the Spring Boot plugin reacts by making various changes
+to the project's configuration. This section describes those changes.
+
+[[reacting-to-other-plugins-java]]
+=== Reacting to the Java plugin
+
+When Gradle's {java-plugin}[`java` plugin] is applied to a project, the Spring Boot
+plugin:
+
+1. Creates a {boot-jar-javadoc}[`BootJar`] task named `bootJar` that will create an
+ executable, fat jar for the project. The jar will contain everything on the runtime
+ classpath of the main source set; classes are packaged in `BOOT-INF/classes` and jars
+ are packaged in `BOOT-INF/lib`
+2. Creates a {software-component}[software component] named `bootJava` that contains the
+ archive produced by the `bootJar` task.
+3. Creates a {boot-run-javadoc}[`BootRun`] task named `bootRun` that can be used to run
+ your application.
+4. Creates a configuration named `bootArchives` that contains the artifact produced by
+ the `bootJar` task.
+5. Configures any `JavaCompile` tasks with no configured encoding to use `UTF-8`.
+
+
+
+[[reacting-to-other-plugins-war]]
+=== Reacting to the war plugin
+
+When Gradle's {war-plugin}[`war` plugin] is applied to a project, the Spring Boot plugin:
+
+1. Creates a {boot-war-javadoc}[`BootWar`] task named `bootWar` that will create an
+ executable, fat war for the project. In addition to the standard packaging, everything
+ in the `providedRuntime` configuration will be packaged in `WEB-INF/lib-provided`.
+2. Creates a {software-component}[software component] named `bootWeb` that contains the
+ archive produced by the `bootWar` task.
+3. Configures the `bootArchives` configuration to contain the artifact produced by the
+ `bootWar` task.
+
+
+
+[[reacting-to-other-plugins-dependency-management]]
+=== Reacting to the dependency management plugin
+
+When the {dependency-management-plugin}[`io.spring.dependency-management` plugin] is
+applied to a project, the Spring Boot plugin will automatically import the
+`spring-boot-dependencies` bom.
+
+
+
+[[reacting-to-other-plugins-application]]
+=== Reacting to the application plugin
+
+When Gradle's {application-plugin}[`application` plugin] is applied to a project, the
+Spring Boot plugin:
+
+1. Creates a `CreateStartScripts` task named `bootStartScripts` that will creates scripts
+ that launch the artifact in the `bootArchives` configuration using `java -jar`.
+2. Creates a new distribution named `boot` and configures it to contain the artifact in
+ the `bootArchives` configuration in its `lib` directory and the start scripts in its
+ `bin` directory.
+3. Configures the `bootRun` task to use the `mainClassName` property as a convention for
+ its `main` property.
+4. Configures the `bootRun` task to use the `applicationDefaultJvmArgs` property as a
+ convention for its `jvmArgs` property.
+5. Configures the `bootJar` task to use the `mainClassName` property as a convention for
+ the `Start-Class` entry in its manifest.
+6. Configures the `bootWar` task to use the `mainClassName` property as a convention for
+ the `Start-Class` entry in its manifest.
+
+
+
+[[reacting-to-other-plugins-maven]]
+=== Reacting to the Maven plugin
+
+When Gradle's {maven-plugin}[`maven` plugin] is applied to a project, the Spring Boot
+plugin will configure the `uploadBootArchives` `Upload` task to ensure that no
+dependencies are declared in the pom that it generates.
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/running.adoc b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/running.adoc
new file mode 100644
index 0000000000..5a8f0cb1ec
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/running.adoc
@@ -0,0 +1,49 @@
+[[running-your-application]]
+== Running your application with Gradle
+
+To run your application without first building an archive use the `bootRun` task:
+
+[source,bash,indent=0,subs="verbatim"]
+----
+ $ ./gradlew bootRun
+----
+
+The `bootRun` task is an instance of
+{boot-run-javadoc}[`BootRun`] which is a `JavaExec` subclass. As such, all of the
+{gradle-dsl}/org.gradle.api.tasks.JavaExec.html[usual configuration options] for executing
+a Java process in Gradle are available to you. The task is automatically configured to use
+the runtime classpath of the main source set.
+
+By default, the main class will be configured automatically by looking for a class with a
+`public static void main(String[])` method in directories on the task's classpath.
+
+The main class can also be configured explicity using the task's `main` property:
+
+[source,groovy,indent=0,subs="verbatim"]
+----
+include::../gradle/running/boot-run-main.gradle[tags=main]
+----
+
+Alternatively, if the {application-plugin}[`application` plugin] has been applied
+its `mainClassName` project property can be used:
+
+[source,groovy,indent=0,subs="verbatim"]
+----
+include::../gradle/running/application-plugin-main-class-name.gradle[tags=main-class]
+----
+
+
+
+[[running-your-application-reloading-resources]]
+=== Reloading resources
+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"]
+----
+include::../gradle/running/boot-run-source-resources.gradle[tags=source-resources]
+----
+
+This makes them reloadable in the live application which can be helpful at development
+time.
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-milestone.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-milestone.gradle
new file mode 100644
index 0000000000..0302ec6f4d
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-milestone.gradle
@@ -0,0 +1,11 @@
+buildscript {
+ repositories {
+ maven { url 'https://repo.spring.io/libs-milestone' }
+ }
+
+ dependencies {
+ classpath 'org.springframework.boot:spring-boot-gradle-plugin:{version}'
+ }
+}
+
+apply plugin: 'org.springframework.boot'
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-release.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-release.gradle
new file mode 100644
index 0000000000..cf13509ffd
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-release.gradle
@@ -0,0 +1,3 @@
+plugins {
+ id 'org.springframework.boot' version '{version}'
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-snapshot.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-snapshot.gradle
new file mode 100644
index 0000000000..c775fa0925
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-snapshot.gradle
@@ -0,0 +1,11 @@
+buildscript {
+ repositories {
+ maven { url 'https://repo.spring.io/libs-snapshot' }
+ }
+
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/typical-plugins.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/typical-plugins.gradle
new file mode 100644
index 0000000000..6549d2bd3e
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/typical-plugins.gradle
@@ -0,0 +1,17 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+// tag::apply[]
+apply plugin: 'java'
+apply plugin: 'io.spring.dependency-management'
+// end::apply[]
+
+task verify {
+ doLast {
+ plugins.getPlugin(org.gradle.api.plugins.JavaPlugin.class)
+ plugins.getPlugin(io.spring.gradle.dependencymanagement.DependencyManagementPlugin.class)
+ }
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-additional.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-additional.gradle
new file mode 100644
index 0000000000..a70995ea38
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-additional.gradle
@@ -0,0 +1,21 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+
+// tag::additional[]
+springBoot {
+ buildInfo {
+ properties {
+ additional = [
+ 'a': 'alpha',
+ 'b': 'bravo'
+ ]
+ }
+ }
+}
+// end::additional[]
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-basic.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-basic.gradle
new file mode 100644
index 0000000000..43329cdd61
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-basic.gradle
@@ -0,0 +1,14 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+
+// tag::build-info[]
+springBoot {
+ buildInfo()
+}
+// end::build-info[]
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-custom-values.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-custom-values.gradle
new file mode 100644
index 0000000000..c8e8b0b416
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-custom-values.gradle
@@ -0,0 +1,21 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+
+// 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-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/custom-version.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/custom-version.gradle
new file mode 100644
index 0000000000..54009ee8c2
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/custom-version.gradle
@@ -0,0 +1,32 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'io.spring.dependency-management'
+
+dependencyManagement {
+ resolutionStrategy {
+ eachDependency {
+ if (it.requested.group == 'org.springframework.boot') {
+ it.useVersion project.bootVersion
+ }
+ }
+ }
+}
+
+// tag::custom-version[]
+ext['slf4j.version'] = '1.7.20'
+// end::custom-version[]
+
+repositories {
+ mavenLocal()
+}
+
+task slf4jVersion {
+ doLast {
+ println dependencyManagement.managedVersions['org.slf4j:slf4j-api']
+ }
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/dependencies.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/dependencies.gradle
new file mode 100644
index 0000000000..ecbf6ffedc
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/dependencies.gradle
@@ -0,0 +1,19 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+plugins {
+ id 'java'
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'io.spring.dependency-management'
+
+// tag::dependencies[]
+dependencies {
+ compile 'org.springframework.boot:spring-boot-starter-web'
+ compile 'org.springframework.boot:spring-boot-starter-data-jpa'
+}
+// end::dependencies[]
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/application-plugin-main-class.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/application-plugin-main-class.gradle
new file mode 100644
index 0000000000..b91321d8fd
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/application-plugin-main-class.gradle
@@ -0,0 +1,13 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+apply plugin: 'application'
+
+// tag::main-class[]
+mainClassName = 'com.example.ExampleApplication'
+// end::main-class[]
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-custom-launch-script.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-custom-launch-script.gradle
new file mode 100644
index 0000000000..c813b9a134
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-custom-launch-script.gradle
@@ -0,0 +1,21 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+
+bootJar {
+ mainClass 'com.example.ExampleApplication'
+}
+
+// tag::custom-launch-script[]
+bootJar {
+ launchScript {
+ included = true
+ script = file('src/custom.script')
+ }
+}
+// end::custom-launch-script[]
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-include-launch-script.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-include-launch-script.gradle
new file mode 100644
index 0000000000..6df82aeb19
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-include-launch-script.gradle
@@ -0,0 +1,20 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+
+bootJar {
+ mainClass 'com.example.ExampleApplication'
+}
+
+// tag::include-launch-script[]
+bootJar {
+ launchScript {
+ included = true
+ }
+}
+// end::include-launch-script[]
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-launch-script-properties.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-launch-script-properties.gradle
new file mode 100644
index 0000000000..1de01e52b5
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-launch-script-properties.gradle
@@ -0,0 +1,21 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+
+bootJar {
+ mainClass 'com.example.ExampleApplication'
+}
+
+// tag::launch-script-properties[]
+bootJar {
+ launchScript {
+ included = true
+ properties 'logFilename': 'example-app.log'
+ }
+}
+// end::launch-script-properties[]
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-main-class.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-main-class.gradle
new file mode 100644
index 0000000000..b3ce53b9ec
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-main-class.gradle
@@ -0,0 +1,14 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+
+// tag::main-class[]
+bootJar {
+ mainClass = 'com.example.ExampleApplication'
+}
+// end::main-class[]
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-manifest-main-class.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-manifest-main-class.gradle
new file mode 100644
index 0000000000..557242e3f1
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-manifest-main-class.gradle
@@ -0,0 +1,16 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+
+// tag::main-class[]
+bootJar {
+ manifest {
+ attributes 'Start-Class': 'com.example.ExampleApplication'
+ }
+}
+// end::main-class[]
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-requires-unpack.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-requires-unpack.gradle
new file mode 100644
index 0000000000..e21da8d831
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-requires-unpack.gradle
@@ -0,0 +1,26 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ runtime 'org.jruby:jruby-complete:1.7.25'
+}
+
+bootJar {
+ mainClass 'com.example.ExampleApplication'
+}
+
+// tag::requires-unpack[]
+bootJar {
+ requiresUnpack '**/jruby-complete-*.jar'
+}
+// end::requires-unpack[]
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-include-devtools.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-include-devtools.gradle
new file mode 100644
index 0000000000..a739250d3b
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-include-devtools.gradle
@@ -0,0 +1,19 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'war'
+
+bootWar {
+ mainClass 'com.example.ExampleApplication'
+ classpath file('spring-boot-devtools-1.2.3.RELEASE.jar')
+}
+
+// tag::include-devtools[]
+bootWar {
+ excludeDevtools = false
+}
+// end::include-devtools[]
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-properties-launcher.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-properties-launcher.gradle
new file mode 100644
index 0000000000..a2d915d905
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-properties-launcher.gradle
@@ -0,0 +1,20 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'war'
+
+bootWar {
+ mainClass 'com.example.ExampleApplication'
+}
+
+// tag::properties-launcher[]
+bootWar {
+ manifest {
+ attributes 'Main-Class': 'org.springframework.boot.loader.PropertiesLauncher'
+ }
+}
+// end::properties-launcher[]
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/war-container-dependency.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/war-container-dependency.gradle
new file mode 100644
index 0000000000..9f8c91b64e
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/war-container-dependency.gradle
@@ -0,0 +1,19 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+plugins {
+ id 'war'
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'io.spring.dependency-management'
+
+// tag::dependencies[]
+dependencies {
+ compile 'org.springframework.boot:spring-boot-starter-web'
+ providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
+}
+// end::dependencies[]
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven-publish.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven-publish.gradle
new file mode 100644
index 0000000000..61ded0c357
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven-publish.gradle
@@ -0,0 +1,31 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+apply plugin: 'maven-publish'
+
+// tag::publishing[]
+publishing {
+ publications {
+ bootJava(MavenPublication) {
+ from components.bootJava
+ }
+ }
+ repositories {
+ maven {
+ url 'https://repo.example.com'
+ }
+ }
+}
+// end::publishing[]
+
+task publishingConfiguration {
+ doLast {
+ println publishing.publications.bootJava
+ println publishing.repositories.maven.url
+ }
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven.gradle
new file mode 100644
index 0000000000..8adefa0643
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven.gradle
@@ -0,0 +1,25 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+apply plugin: 'maven'
+
+// tag::upload[]
+uploadBootArchives {
+ repositories {
+ mavenDeployer {
+ repository url: 'https://repo.example.com'
+ }
+ }
+}
+// end::upload[]
+
+task deployerRepository {
+ doLast {
+ println uploadBootArchives.repositories.mavenDeployer.repository.url
+ }
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/application-plugin-main-class-name.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/application-plugin-main-class-name.gradle
new file mode 100644
index 0000000000..6e05ceaa3d
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/application-plugin-main-class-name.gradle
@@ -0,0 +1,19 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+apply plugin: 'application'
+
+// tag::main-class[]
+mainClassName = 'com.example.ExampleApplication'
+// end::main-class[]
+
+task configuredMainClass {
+ doLast {
+ println bootRun.main
+ }
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-main.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-main.gradle
new file mode 100644
index 0000000000..82907a4c4e
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-main.gradle
@@ -0,0 +1,20 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+
+// tag::main[]
+bootRun {
+ main = 'com.example.ExampleApplication'
+}
+// end::main[]
+
+task configuredMainClass {
+ doLast {
+ println bootRun.main
+ }
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-source-resources.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-source-resources.gradle
new file mode 100644
index 0000000000..19b016b526
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-source-resources.gradle
@@ -0,0 +1,20 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+
+// tag::source-resources[]
+bootRun {
+ sourceResources sourceSets.main
+}
+// end::source-resources[]
+
+task configuredClasspath {
+ doLast {
+ println bootRun.classpath.files
+ }
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/javadoc/spring-javadoc.css b/spring-boot-tools/spring-boot-gradle-plugin/src/main/javadoc/spring-javadoc.css
new file mode 100644
index 0000000000..06ad42277c
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/javadoc/spring-javadoc.css
@@ -0,0 +1,599 @@
+/* Javadoc style sheet */
+/*
+Overall document style
+*/
+
+@import url('resources/fonts/dejavu.css');
+
+body {
+ background-color:#ffffff;
+ color:#353833;
+ font-family:'DejaVu Sans', Arial, Helvetica, sans-serif;
+ font-size:14px;
+ margin:0;
+}
+a:link, a:visited {
+ text-decoration:none;
+ color:#4A6782;
+}
+a:hover, a:focus {
+ text-decoration:none;
+ color:#bb7a2a;
+}
+a:active {
+ text-decoration:none;
+ color:#4A6782;
+}
+a[name] {
+ color:#353833;
+}
+a[name]:hover {
+ text-decoration:none;
+ color:#353833;
+}
+pre {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+}
+h1 {
+ font-size:20px;
+}
+h2 {
+ font-size:18px;
+}
+h3 {
+ font-size:16px;
+ font-style:italic;
+}
+h4 {
+ font-size:13px;
+}
+h5 {
+ font-size:12px;
+}
+h6 {
+ font-size:11px;
+}
+ul {
+ list-style-type:disc;
+}
+code, tt {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+ padding-top:4px;
+ margin-top:8px;
+ line-height:1.4em;
+}
+dt code {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+ padding-top:4px;
+}
+table tr td dt code {
+ font-family:'DejaVu Sans Mono', monospace;
+ font-size:14px;
+ vertical-align:top;
+ padding-top:4px;
+}
+sup {
+ font-size:8px;
+}
+/*
+Document title and Copyright styles
+*/
+.clear {
+ clear:both;
+ height:0px;
+ overflow:hidden;
+}
+.aboutLanguage {
+ float:right;
+ padding:0px 21px;
+ font-size:11px;
+ z-index:200;
+ margin-top:-9px;
+}
+.legalCopy {
+ margin-left:.5em;
+}
+.bar a, .bar a:link, .bar a:visited, .bar a:active {
+ color:#FFFFFF;
+ text-decoration:none;
+}
+.bar a:hover, .bar a:focus {
+ color:#bb7a2a;
+}
+.tab {
+ background-color:#0066FF;
+ color:#ffffff;
+ padding:8px;
+ width:5em;
+ font-weight:bold;
+}
+/*
+Navigation bar styles
+*/
+.bar {
+ background-color:#4D7A97;
+ color:#FFFFFF;
+ padding:.8em .5em .4em .8em;
+ height:auto;/*height:1.8em;*/
+ font-size:11px;
+ margin:0;
+}
+.topNav {
+ background-color:#4D7A97;
+ color:#FFFFFF;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+ font-size:12px;
+}
+.bottomNav {
+ margin-top:10px;
+ background-color:#4D7A97;
+ color:#FFFFFF;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+ font-size:12px;
+}
+.subNav {
+ background-color:#dee3e9;
+ float:left;
+ width:100%;
+ overflow:hidden;
+ font-size:12px;
+}
+.subNav div {
+ clear:left;
+ float:left;
+ padding:0 0 5px 6px;
+ text-transform:uppercase;
+}
+ul.navList, ul.subNavList {
+ float:left;
+ margin:0 25px 0 0;
+ padding:0;
+}
+ul.navList li{
+ list-style:none;
+ float:left;
+ padding: 5px 6px;
+ text-transform:uppercase;
+}
+ul.subNavList li{
+ list-style:none;
+ float:left;
+}
+.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {
+ color:#FFFFFF;
+ text-decoration:none;
+ text-transform:uppercase;
+}
+.topNav a:hover, .bottomNav a:hover {
+ text-decoration:none;
+ color:#bb7a2a;
+ text-transform:uppercase;
+}
+.navBarCell1Rev {
+ background-color:#F8981D;
+ color:#253441;
+ margin: auto 5px;
+}
+.skipNav {
+ position:absolute;
+ top:auto;
+ left:-9999px;
+ overflow:hidden;
+}
+/*
+Page header and footer styles
+*/
+.header, .footer {
+ clear:both;
+ margin:0 20px;
+ padding:5px 0 0 0;
+}
+.indexHeader {
+ margin:10px;
+ position:relative;
+}
+.indexHeader span{
+ margin-right:15px;
+}
+.indexHeader h1 {
+ font-size:13px;
+}
+.title {
+ color:#2c4557;
+ margin:10px 0;
+}
+.subTitle {
+ margin:5px 0 0 0;
+}
+.header ul {
+ margin:0 0 15px 0;
+ padding:0;
+}
+.footer ul {
+ margin:20px 0 5px 0;
+}
+.header ul li, .footer ul li {
+ list-style:none;
+ font-size:13px;
+}
+/*
+Heading styles
+*/
+div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
+ background-color:#dee3e9;
+ border:1px solid #d0d9e0;
+ margin:0 0 6px -8px;
+ padding:7px 5px;
+}
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+ background-color:#dee3e9;
+ border:1px solid #d0d9e0;
+ margin:0 0 6px -8px;
+ padding:7px 5px;
+}
+ul.blockList ul.blockList li.blockList h3 {
+ padding:0;
+ margin:15px 0;
+}
+ul.blockList li.blockList h2 {
+ padding:0px 0 20px 0;
+}
+/*
+Page layout container styles
+*/
+.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {
+ clear:both;
+ padding:10px 20px;
+ position:relative;
+}
+.indexContainer {
+ margin:10px;
+ position:relative;
+ font-size:12px;
+}
+.indexContainer h2 {
+ font-size:13px;
+ padding:0 0 3px 0;
+}
+.indexContainer ul {
+ margin:0;
+ padding:0;
+}
+.indexContainer ul li {
+ list-style:none;
+ padding-top:2px;
+}
+.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
+ font-size:12px;
+ font-weight:bold;
+ margin:10px 0 0 0;
+ color:#4E4E4E;
+}
+.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
+ margin:5px 0 10px 0px;
+ font-size:14px;
+ font-family:'DejaVu Sans Mono',monospace;
+}
+.serializedFormContainer dl.nameValue dt {
+ margin-left:1px;
+ font-size:1.1em;
+ display:inline;
+ font-weight:bold;
+}
+.serializedFormContainer dl.nameValue dd {
+ margin:0 0 0 1px;
+ font-size:1.1em;
+ display:inline;
+}
+/*
+List styles
+*/
+ul.horizontal li {
+ display:inline;
+ font-size:0.9em;
+}
+ul.inheritance {
+ margin:0;
+ padding:0;
+}
+ul.inheritance li {
+ display:inline;
+ list-style:none;
+}
+ul.inheritance li ul.inheritance {
+ margin-left:15px;
+ padding-left:15px;
+ padding-top:1px;
+}
+ul.blockList, ul.blockListLast {
+ margin:10px 0 10px 0;
+ padding:0;
+}
+ul.blockList li.blockList, ul.blockListLast li.blockList {
+ list-style:none;
+ margin-bottom:15px;
+ line-height:1.4;
+}
+ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {
+ padding:0px 20px 5px 10px;
+ border:1px solid #ededed;
+ background-color:#f8f8f8;
+}
+ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {
+ padding:0 0 5px 8px;
+ background-color:#ffffff;
+ border:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockList {
+ margin-left:0;
+ padding-left:0;
+ padding-bottom:15px;
+ border:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
+ list-style:none;
+ border-bottom:none;
+ padding-bottom:0;
+}
+table tr td dl, table tr td dl dt, table tr td dl dd {
+ margin-top:0;
+ margin-bottom:1px;
+}
+/*
+Table styles
+*/
+.overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary {
+ width:100%;
+ border-left:1px solid #EEE;
+ border-right:1px solid #EEE;
+ border-bottom:1px solid #EEE;
+}
+.overviewSummary, .memberSummary {
+ padding:0px;
+}
+.overviewSummary caption, .memberSummary caption, .typeSummary caption,
+.useSummary caption, .constantsSummary caption, .deprecatedSummary caption {
+ position:relative;
+ text-align:left;
+ background-repeat:no-repeat;
+ color:#253441;
+ font-weight:bold;
+ clear:none;
+ overflow:hidden;
+ padding:0px;
+ padding-top:10px;
+ padding-left:1px;
+ margin:0px;
+ white-space:pre;
+}
+.overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link,
+.useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link,
+.overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover,
+.useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover,
+.overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active,
+.useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active,
+.overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited,
+.useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited {
+ color:#FFFFFF;
+}
+.overviewSummary caption span, .memberSummary caption span, .typeSummary caption span,
+.useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ padding-bottom:7px;
+ display:inline-block;
+ float:left;
+ background-color:#F8981D;
+ border: none;
+ height:16px;
+}
+.memberSummary caption span.activeTableTab span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ margin-right:3px;
+ display:inline-block;
+ float:left;
+ background-color:#F8981D;
+ height:16px;
+}
+.memberSummary caption span.tableTab span {
+ white-space:nowrap;
+ padding-top:5px;
+ padding-left:12px;
+ padding-right:12px;
+ margin-right:3px;
+ display:inline-block;
+ float:left;
+ background-color:#4D7A97;
+ height:16px;
+}
+.memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab {
+ padding-top:0px;
+ padding-left:0px;
+ padding-right:0px;
+ background-image:none;
+ float:none;
+ display:inline;
+}
+.overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd,
+.useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd {
+ display:none;
+ width:5px;
+ position:relative;
+ float:left;
+ background-color:#F8981D;
+}
+.memberSummary .activeTableTab .tabEnd {
+ display:none;
+ width:5px;
+ margin-right:3px;
+ position:relative;
+ float:left;
+ background-color:#F8981D;
+}
+.memberSummary .tableTab .tabEnd {
+ display:none;
+ width:5px;
+ margin-right:3px;
+ position:relative;
+ background-color:#4D7A97;
+ float:left;
+
+}
+.overviewSummary td, .memberSummary td, .typeSummary td,
+.useSummary td, .constantsSummary td, .deprecatedSummary td {
+ text-align:left;
+ padding:0px 0px 12px 10px;
+ width:100%;
+}
+th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th,
+td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{
+ vertical-align:top;
+ padding-right:0px;
+ padding-top:8px;
+ padding-bottom:3px;
+}
+th.colFirst, th.colLast, th.colOne, .constantsSummary th {
+ background:#dee3e9;
+ text-align:left;
+ padding:8px 3px 3px 7px;
+}
+td.colFirst, th.colFirst {
+ white-space:nowrap;
+ font-size:13px;
+}
+td.colLast, th.colLast {
+ font-size:13px;
+}
+td.colOne, th.colOne {
+ font-size:13px;
+}
+.overviewSummary td.colFirst, .overviewSummary th.colFirst,
+.overviewSummary td.colOne, .overviewSummary th.colOne,
+.memberSummary td.colFirst, .memberSummary th.colFirst,
+.memberSummary td.colOne, .memberSummary th.colOne,
+.typeSummary td.colFirst{
+ width:25%;
+ vertical-align:top;
+}
+td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover {
+ font-weight:bold;
+}
+.tableSubHeadingColor {
+ background-color:#EEEEFF;
+}
+.altColor {
+ background-color:#FFFFFF;
+}
+.rowColor {
+ background-color:#EEEEEF;
+}
+/*
+Content styles
+*/
+.description pre {
+ margin-top:0;
+}
+.deprecatedContent {
+ margin:0;
+ padding:10px 0;
+}
+.docSummary {
+ padding:0;
+}
+
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+ font-style:normal;
+}
+
+div.block {
+ font-size:14px;
+ font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif;
+}
+
+td.colLast div {
+ padding-top:0px;
+}
+
+
+td.colLast a {
+ padding-bottom:3px;
+}
+/*
+Formatting effect styles
+*/
+.sourceLineNo {
+ color:green;
+ padding:0 30px 0 0;
+}
+h1.hidden {
+ visibility:hidden;
+ overflow:hidden;
+ font-size:10px;
+}
+.block {
+ display:block;
+ margin:3px 10px 2px 0px;
+ color:#474747;
+}
+.deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink,
+.overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel,
+.seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink {
+ font-weight:bold;
+}
+.deprecationComment, .emphasizedPhrase, .interfaceName {
+ font-style:italic;
+}
+
+div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase,
+div.block div.block span.interfaceName {
+ font-style:normal;
+}
+
+div.contentContainer ul.blockList li.blockList h2{
+ padding-bottom:0px;
+}
+
+
+
+/*
+Spring
+*/
+
+pre.code {
+ background-color: #F8F8F8;
+ border: 1px solid #CCCCCC;
+ border-radius: 3px 3px 3px 3px;
+ overflow: auto;
+ padding: 10px;
+ margin: 4px 20px 2px 0px;
+}
+
+pre.code code, pre.code code * {
+ font-size: 1em;
+}
+
+pre.code code, pre.code code * {
+ padding: 0 !important;
+ margin: 0 !important;
+}
+
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/GettingStartedDocumentationTests.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/GettingStartedDocumentationTests.java
new file mode 100644
index 0000000000..4c05d9f646
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/GettingStartedDocumentationTests.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2012-2017 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.docs;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.springframework.boot.gradle.testkit.GradleBuild;
+
+/**
+ * Tests for the getting started documentation.
+ *
+ * @author Andy Wilkinson
+ */
+public class GettingStartedDocumentationTests {
+
+ @Rule
+ public GradleBuild gradleBuild = new GradleBuild();
+
+ @Test
+ public void applyPluginSnapshotExampleEvaluatesSuccessfully() {
+ this.gradleBuild
+ .script("src/main/gradle/getting-started/apply-plugin-snapshot.gradle")
+ .build();
+ }
+
+ @Test
+ public void typicalPluginsAppliesExceptedPlugins() {
+ this.gradleBuild.script("src/main/gradle/getting-started/typical-plugins.gradle")
+ .build("verify");
+ }
+
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/IntegratingWithActuatorDocumentationTests.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/IntegratingWithActuatorDocumentationTests.java
new file mode 100644
index 0000000000..8ba0219bc2
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/IntegratingWithActuatorDocumentationTests.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2012-2017 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.docs;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.springframework.boot.gradle.testkit.GradleBuild;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for the generating build info documentation.
+ *
+ * @author Andy Wilkinson
+ */
+public class IntegratingWithActuatorDocumentationTests {
+
+ @Rule
+ public GradleBuild gradleBuild = new GradleBuild();
+
+ @Test
+ public void basicBuildInfo() throws IOException {
+ this.gradleBuild
+ .script("src/main/gradle/integrating-with-actuator/build-info-basic.gradle")
+ .build("bootBuildInfo");
+ assertThat(new File(this.gradleBuild.getProjectDir(),
+ "build/resources/main/META-INF/build-info.properties")).isFile();
+ }
+
+ @Test
+ public void buildInfoCustomValues() throws IOException {
+ this.gradleBuild
+ .script("src/main/gradle/integrating-with-actuator/build-info-custom-values.gradle")
+ .build("bootBuildInfo");
+ File file = new File(this.gradleBuild.getProjectDir(),
+ "build/resources/main/META-INF/build-info.properties");
+ assertThat(file).isFile();
+ Properties properties = buildInfoProperties(file);
+ assertThat(properties).containsEntry("build.artifact", "example-app");
+ assertThat(properties).containsEntry("build.version", "1.2.3");
+ assertThat(properties).containsEntry("build.group", "com.example");
+ assertThat(properties).containsEntry("build.name", "Example application");
+ }
+
+ @Test
+ public void buildInfoAdditional() throws IOException {
+ this.gradleBuild
+ .script("src/main/gradle/integrating-with-actuator/build-info-additional.gradle")
+ .build("bootBuildInfo");
+ File file = new File(this.gradleBuild.getProjectDir(),
+ "build/resources/main/META-INF/build-info.properties");
+ assertThat(file).isFile();
+ Properties properties = buildInfoProperties(file);
+ assertThat(properties).containsEntry("build.a", "alpha");
+ assertThat(properties).containsEntry("build.b", "bravo");
+ }
+
+ private Properties buildInfoProperties(File file) {
+ assertThat(file).isFile();
+ Properties properties = new Properties();
+ try (FileReader reader = new FileReader(file)) {
+ properties.load(reader);
+ return properties;
+ }
+ catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/ManagingDependenciesDocumentationTests.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/ManagingDependenciesDocumentationTests.java
new file mode 100644
index 0000000000..0d69c8a0b6
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/ManagingDependenciesDocumentationTests.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012-2017 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.docs;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.springframework.boot.gradle.testkit.GradleBuild;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for the managing dependencies documentation.
+ *
+ * @author Andy Wilkinson
+ */
+public class ManagingDependenciesDocumentationTests {
+
+ @Rule
+ public GradleBuild gradleBuild = new GradleBuild();
+
+ @Test
+ public void dependenciesExampleEvaluatesSuccessfully() {
+ this.gradleBuild
+ .script("src/main/gradle/managing-dependencies/dependencies.gradle")
+ .build();
+ }
+
+ @Test
+ public void customManagedVersions() {
+ assertThat(this.gradleBuild
+ .script("src/main/gradle/managing-dependencies/custom-version.gradle")
+ .build("slf4jVersion").getOutput()).contains("1.7.20");
+ }
+
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PackagingDocumentationTests.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PackagingDocumentationTests.java
new file mode 100644
index 0000000000..03afebb19c
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PackagingDocumentationTests.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2012-2017 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.docs;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.springframework.boot.gradle.testkit.GradleBuild;
+import org.springframework.util.FileCopyUtils;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for the packaging documentation.
+ *
+ * @author Andy Wilkinson
+ */
+public class PackagingDocumentationTests {
+
+ @Rule
+ public GradleBuild gradleBuild = new GradleBuild();
+
+ @Test
+ public void warContainerDependencyEvaluatesSuccessfully() {
+ this.gradleBuild
+ .script("src/main/gradle/packaging/war-container-dependency.gradle")
+ .build();
+ }
+
+ @Test
+ public void bootJarMainClass() throws IOException {
+ this.gradleBuild.script("src/main/gradle/packaging/boot-jar-main-class.gradle")
+ .build("bootJar");
+ File file = new File(this.gradleBuild.getProjectDir(),
+ "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
+ assertThat(file).isFile();
+ try (JarFile jar = new JarFile(file)) {
+ assertThat(jar.getManifest().getMainAttributes().getValue("Start-Class"))
+ .isEqualTo("com.example.ExampleApplication");
+ }
+ }
+
+ @Test
+ public void bootJarManifestMainClass() throws IOException {
+ this.gradleBuild
+ .script("src/main/gradle/packaging/boot-jar-manifest-main-class.gradle")
+ .build("bootJar");
+ File file = new File(this.gradleBuild.getProjectDir(),
+ "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
+ assertThat(file).isFile();
+ try (JarFile jar = new JarFile(file)) {
+ assertThat(jar.getManifest().getMainAttributes().getValue("Start-Class"))
+ .isEqualTo("com.example.ExampleApplication");
+ }
+ }
+
+ @Test
+ public void applicationPluginMainClass() throws IOException {
+ this.gradleBuild
+ .script("src/main/gradle/packaging/application-plugin-main-class.gradle")
+ .build("bootJar");
+ File file = new File(this.gradleBuild.getProjectDir(),
+ "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
+ assertThat(file).isFile();
+ try (JarFile jar = new JarFile(file)) {
+ assertThat(jar.getManifest().getMainAttributes().getValue("Start-Class"))
+ .isEqualTo("com.example.ExampleApplication");
+ }
+ }
+
+ @Test
+ 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")
+ .build("bootWar");
+ File file = new File(this.gradleBuild.getProjectDir(),
+ "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".war");
+ assertThat(file).isFile();
+ try (JarFile jar = new JarFile(file)) {
+ assertThat(jar.getEntry("WEB-INF/lib/spring-boot-devtools-1.2.3.RELEASE.jar"))
+ .isNotNull();
+ }
+ }
+
+ @Test
+ public void bootJarRequiresUnpack() throws IOException {
+ this.gradleBuild
+ .script("src/main/gradle/packaging/boot-jar-requires-unpack.gradle")
+ .build("bootJar");
+ File file = new File(this.gradleBuild.getProjectDir(),
+ "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
+ assertThat(file).isFile();
+ try (JarFile jar = new JarFile(file)) {
+ JarEntry entry = jar.getJarEntry("BOOT-INF/lib/jruby-complete-1.7.25.jar");
+ assertThat(entry).isNotNull();
+ assertThat(entry.getComment()).startsWith("UNPACK:");
+ }
+ }
+
+ @Test
+ public void bootJarIncludeLaunchScript() throws IOException {
+ this.gradleBuild
+ .script("src/main/gradle/packaging/boot-jar-include-launch-script.gradle")
+ .build("bootJar");
+ File file = new File(this.gradleBuild.getProjectDir(),
+ "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
+ assertThat(file).isFile();
+ assertThat(FileCopyUtils.copyToString(new FileReader(file)))
+ .startsWith("#!/bin/bash");
+ }
+
+ @Test
+ public void bootJarLaunchScriptProperties() throws IOException {
+ this.gradleBuild
+ .script("src/main/gradle/packaging/boot-jar-launch-script-properties.gradle")
+ .build("bootJar");
+ File file = new File(this.gradleBuild.getProjectDir(),
+ "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
+ assertThat(file).isFile();
+ assertThat(FileCopyUtils.copyToString(new FileReader(file)))
+ .contains("example-app.log");
+ }
+
+ @Test
+ public void bootJarCustomLaunchScript() throws IOException {
+ File customScriptFile = new File(this.gradleBuild.getProjectDir(),
+ "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")
+ .build("bootJar");
+ File file = new File(this.gradleBuild.getProjectDir(),
+ "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
+ assertThat(file).isFile();
+ assertThat(FileCopyUtils.copyToString(new FileReader(file))).startsWith("custom");
+ }
+
+ @Test
+ public void bootWarPropertiesLauncher() throws IOException {
+ this.gradleBuild
+ .script("src/main/gradle/packaging/boot-war-properties-launcher.gradle")
+ .build("bootWar");
+ File file = new File(this.gradleBuild.getProjectDir(),
+ "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".war");
+ assertThat(file).isFile();
+ try (JarFile jar = new JarFile(file)) {
+ assertThat(jar.getManifest().getMainAttributes().getValue("Main-Class"))
+ .isEqualTo("org.springframework.boot.loader.PropertiesLauncher");
+ }
+ }
+
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PublishingDocumentationTests.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PublishingDocumentationTests.java
new file mode 100644
index 0000000000..b57a0ab60e
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PublishingDocumentationTests.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2012-2017 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.docs;
+
+import java.io.IOException;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.springframework.boot.gradle.testkit.GradleBuild;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for the publishing documentation.
+ *
+ * @author Andy Wilkinson
+ */
+public class PublishingDocumentationTests {
+
+ @Rule
+ public GradleBuild gradleBuild = new GradleBuild();
+
+ @Test
+ public void mavenUpload() throws IOException {
+ assertThat(this.gradleBuild.script("src/main/gradle/publishing/maven.gradle")
+ .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");
+ }
+
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/RunningDocumentationTests.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/RunningDocumentationTests.java
new file mode 100644
index 0000000000..742ed2b9f1
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/RunningDocumentationTests.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2012-2017 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.docs;
+
+import java.io.IOException;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.springframework.boot.gradle.testkit.GradleBuild;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for the integrating with Actuator documentation.
+ *
+ * @author Andy Wilkinson
+ */
+public class RunningDocumentationTests {
+
+ @Rule
+ public GradleBuild gradleBuild = new GradleBuild();
+
+ @Test
+ public void bootRunMain() throws IOException {
+ assertThat(this.gradleBuild.script("src/main/gradle/running/boot-run-main.gradle")
+ .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")
+ .build("configuredMainClass").getOutput())
+ .contains("com.example.ExampleApplication");
+ }
+
+ @Test
+ public void bootRunSourceResources() throws IOException {
+ assertThat(this.gradleBuild
+ .script("src/main/gradle/running/boot-run-source-resources.gradle")
+ .build("configuredClasspath").getOutput()).contains("src/main/resources");
+ }
+
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java
index cc8b8cb389..6dfde693bc 100644
--- a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java
@@ -18,10 +18,9 @@ package org.springframework.boot.gradle.testkit;
import java.io.File;
import java.io.FileReader;
+import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
-import java.nio.file.Files;
-import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -41,6 +40,7 @@ import org.xml.sax.InputSource;
import org.springframework.asm.ClassVisitor;
import org.springframework.boot.loader.tools.LaunchScript;
+import org.springframework.util.FileCopyUtils;
/**
* A {@link TestRule} for running a Gradle build using {@link GradleRunner}.
@@ -143,9 +143,10 @@ public class GradleBuild implements TestRule {
}
public GradleRunner prepareRunner(String... arguments) throws IOException {
- Files.copy(new File(this.script).toPath(),
- new File(this.projectDir, "build.gradle").toPath(),
- StandardCopyOption.REPLACE_EXISTING);
+ String scriptContent = FileCopyUtils.copyToString(new FileReader(this.script))
+ .replace("{version}", getBootVersion());
+ FileCopyUtils.copy(scriptContent,
+ new FileWriter(new File(this.projectDir, "build.gradle")));
GradleRunner gradleRunner = GradleRunner.create().withProjectDir(this.projectDir)
.forwardOutput();
List allArguments = new ArrayList();