Commit 01166381 authored by Andy Wilkinson's avatar Andy Wilkinson

Provide separate documentation (API and reference) for Gradle plugin

parent 47c0c3c0
...@@ -853,6 +853,15 @@ ...@@ -853,6 +853,15 @@
</outputDirectory> </outputDirectory>
<excludes>META-INF/**</excludes> <excludes>META-INF/**</excludes>
</artifactItem> </artifactItem>
<artifactItem>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-gradle-plugin</artifactId>
<version>${project.version}</version>
<classifier>docs</classifier>
<type>zip</type>
<outputDirectory>${project.build.directory}/contents/gradle-plugin</outputDirectory>
<excludes>META-INF/**</excludes>
</artifactItem>
</artifactItems> </artifactItems>
</configuration> </configuration>
</execution> </execution>
......
...@@ -164,516 +164,11 @@ Advanced configuration options and examples are available in the ...@@ -164,516 +164,11 @@ Advanced configuration options and examples are available in the
[[build-tool-plugins-gradle-plugin]] [[build-tool-plugins-gradle-plugin]]
== Spring Boot Gradle plugin == Spring Boot Gradle plugin
The Spring Boot Gradle Plugin provides Spring Boot support in Gradle, allowing you to The {spring-boot-gradle-plugin}[Spring Boot Gradle Plugin] provides Spring Boot support
package executable jar or war archives, run Spring Boot applications and use the in Gradle, allowing you to package executable jar or war archives, run Spring Boot
dependency management provided by `spring-boot-dependencies`. 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.
[[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 <<appendix-dependency-versions, appendix>>.
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
<<build-tool-plugins-gradle-repackage-configuration,`bootRepackage` task>>. 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 <<build-tool-plugins-gradle-repackage-configuration>> 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 "`<<howto-create-a-deployable-war-file>>`" 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 <<using-spring-boot.adoc#using-boot-devtools,`devtools`>> 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
<<build-tool-plugins-gradle-configuration-layouts,available layouts for more details>>.
|`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
<<appendix-executable-jar-format.adoc#executable-jar-jar-file-structure,JAR layout>>.
|Yes
|`WAR`
|Executable
<<appendix-executable-jar-format.adoc#executable-jar-war-file-structure,WAR layout>>.
`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
<<appendix-executable-jar-format.adoc#executable-jar-property-launcher-features,`PropertiesLauncher`>>.
| 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 <<build-tool-plugins-gradle-dependencies-without-versions, declaring
dependencies without versions>> 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"
}
}
}
}
}
}
}
}
----
......
...@@ -827,12 +827,12 @@ Example in Gradle: ...@@ -827,12 +827,12 @@ Example in Gradle:
[source,groovy,indent=0,subs="verbatim,quotes,attributes"] [source,groovy,indent=0,subs="verbatim,quotes,attributes"]
---- ----
configurations { configurations {
compile.exclude module: "spring-boot-starter-tomcat" compile.exclude module: 'spring-boot-starter-tomcat'
} }
dependencies { dependencies {
compile("org.springframework.boot:spring-boot-starter-web:{spring-boot-version}") compile 'org.springframework.boot:spring-boot-starter-web'
compile("org.springframework.boot:spring-boot-starter-jetty:{spring-boot-version}") compile 'org.springframework.boot:spring-boot-starter-jetty'
// ... // ...
} }
---- ----
...@@ -881,12 +881,12 @@ Example in Gradle: ...@@ -881,12 +881,12 @@ Example in Gradle:
[source,groovy,indent=0,subs="verbatim,quotes,attributes"] [source,groovy,indent=0,subs="verbatim,quotes,attributes"]
---- ----
configurations { configurations {
compile.exclude module: "spring-boot-starter-tomcat" compile.exclude module: 'spring-boot-starter-tomcat'
} }
dependencies { dependencies {
compile("org.springframework.boot:spring-boot-starter-web:{spring-boot-version}") compile 'org.springframework.boot:spring-boot-starter-web'
compile("org.springframework.boot:spring-boot-starter-undertow:{spring-boot-version}") compile 'org.springframework.boot:spring-boot-starter-undertow'
// ... // ...
} }
---- ----
...@@ -2355,9 +2355,11 @@ To configure IntelliJ IDEA correctly you can use the `idea` Gradle plugin: ...@@ -2355,9 +2355,11 @@ To configure IntelliJ IDEA correctly you can use the `idea` Gradle plugin:
[source,groovy,indent=0,subs="verbatim,attributes"] [source,groovy,indent=0,subs="verbatim,attributes"]
---- ----
buildscript { buildscript {
repositories { jcenter() } repositories {
jcenter()
}
dependencies { 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' classpath 'org.springframework:springloaded:1.2.6.RELEASE'
} }
} }
...@@ -2502,16 +2504,7 @@ the artifact yourself instead of overriding the property. ...@@ -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 WARNING: Each Spring Boot release is designed and tested against a specific set of
third-party dependencies. Overriding versions may cause compatibility issues. 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]] [[howto-create-an-executable-jar-with-maven]]
=== 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 ...@@ -2593,15 +2586,6 @@ To configure a classifier of `exec` in Maven, the following configuration can be
</build> </build>
---- ----
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]] [[howto-extract-specific-libraries-when-an-executable-jar-runs]]
...@@ -2637,15 +2621,6 @@ you would add the following configuration: ...@@ -2637,15 +2621,6 @@ you would add the following configuration:
</build> </build>
---- ----
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]] [[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: ...@@ -2689,29 +2664,6 @@ jar must be the main artifact and you can add a classified jar for the library:
</build> </build>
---- ----
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]] [[howto-remote-debug-maven-run]]
...@@ -2723,34 +2675,6 @@ Check {spring-boot-maven-plugin-site}/examples/run-debug.html[this example] for ...@@ -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]] [[howto-build-an-executable-archive-with-ant]]
=== Build an executable archive from Ant without using spring-boot-antlib === 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 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: ...@@ -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 NOTE: `providedRuntime` is prefered to Gradle's `compileOnly` configuration as, among other
or later), you should continue to use `providedRuntime`. Among other limitations, limitations, `compileOnly` dependencies are not on the test classpath so any web-based
`compileOnly` dependencies are not on the test classpath so any web-based integration integration tests will fail.
tests will fail.
If you're using the <<build-tool-plugins.adoc#build-tool-plugins, Spring Boot build tools>>, If you're using the <<build-tool-plugins.adoc#build-tool-plugins, Spring Boot build tools>>,
marking the embedded servlet container dependency as provided will produce an executable war marking the embedded servlet container dependency as provided will produce an executable war
......
...@@ -34,7 +34,8 @@ Phillip Webb; Dave Syer; Josh Long; Stéphane Nicoll; Rob Winch; Andy Wilkinson; ...@@ -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 :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: https://github.com/spring-gradle-plugins/dependency-management-plugin
:dependency-management-plugin-documentation: {dependency-management-plugin}/blob/master/README.md :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-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-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 :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; ...@@ -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 :propdeps-plugin: https://github.com/spring-projects/gradle-plugins/tree/master/propdeps-plugin
:ant-manual: http://ant.apache.org/manual :ant-manual: http://ant.apache.org/manual
:code-examples: ../java/org/springframework/boot :code-examples: ../java/org/springframework/boot
:gradle-user-guide: https://docs.gradle.org/2.14.1/userguide :gradle-user-guide: https://docs.gradle.org/3.4.1/userguide
:gradle-dsl: https://docs.gradle.org/2.14.1/dsl
// ====================================================================================== // ======================================================================================
include::documentation-overview.adoc[] include::documentation-overview.adoc[]
......
...@@ -41,8 +41,8 @@ feel that's necessary. ...@@ -41,8 +41,8 @@ feel that's necessary.
The curated list contains all the spring modules that you can use with Spring Boot as 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 well as a refined list of third party libraries. The list is available as a standard
<<using-boot-maven-without-a-parent,Bills of Materials (`spring-boot-dependencies`)>> <<using-boot-maven-without-a-parent,Bills of Materials (`spring-boot-dependencies`)>>
and additional dedicated support for <<using-boot-maven-parent-pom,Maven>> and that can be used with both <<using-boot-maven-parent-pom,Maven>> and
<<build-tool-plugins-gradle-dependency-management,Gradle>> are available as well. {spring-boot-gradle-plugin}[Gradle].
WARNING: Each release of Spring Boot is associated with a base version of the Spring 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. Framework so we **highly** recommend you to not specify its version on your own.
...@@ -194,70 +194,8 @@ the parent. ...@@ -194,70 +194,8 @@ the parent.
[[using-boot-gradle]] [[using-boot-gradle]]
=== Gradle === Gradle
Gradle users can directly import '`starters`' in their `dependencies` section. Unlike To learn about using Spring Boot with Gradle, please refer to the
Maven, there is no "`super parent`" to import to share some configuration. {spring-boot-gradle-plugin}[documentation for Spring Boot's Gradle plugin].
[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 <<build-tool-plugins.adoc#build-tool-plugins-gradle-plugin,
`spring-boot-gradle-plugin`>> is also available and provides tasks to create executable
jars and run projects from source. It also provides
<<build-tool-plugins-gradle-dependency-management, dependency management>> 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")
}
----
...@@ -704,8 +642,8 @@ You might also want to use the useful operating system environment variable: ...@@ -704,8 +642,8 @@ You might also want to use the useful operating system environment variable:
[[using-boot-running-with-the-gradle-plugin]] [[using-boot-running-with-the-gradle-plugin]]
=== Using the Gradle plugin === Using the Gradle plugin
The Spring Boot Gradle plugin also includes a `bootRun` task which can be used to run 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 your application in an exploded form. The `bootRun` task is added whenever you apply the
the `spring-boot-gradle-plugin`: the `org.springframework.boot` and `java` plugins:
[indent=0,subs="attributes"] [indent=0,subs="attributes"]
---- ----
......
...@@ -46,7 +46,6 @@ jar { ...@@ -46,7 +46,6 @@ jar {
} }
} }
eclipseJdt { eclipseJdt {
inputFile = rootProject.file('../../eclipse/org.eclipse.jdt.core.prefs') inputFile = rootProject.file('../../eclipse/org.eclipse.jdt.core.prefs')
doLast { doLast {
...@@ -56,6 +55,18 @@ eclipseJdt { ...@@ -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) { task sourcesJar(type: Jar) {
classifier = 'sources' classifier = 'sources'
from sourceSets.main.allSource from sourceSets.main.allSource
......
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
<argument>clean</argument> <argument>clean</argument>
<argument>build</argument> <argument>build</argument>
<argument>-Pversion=${project.version}</argument> <argument>-Pversion=${project.version}</argument>
<argument>-Pdescription=${project.description}</argument>
</arguments> </arguments>
</configuration> </configuration>
<goals> <goals>
...@@ -112,5 +113,138 @@ ...@@ -112,5 +113,138 @@
<gradle.executable>gradlew.bat</gradle.executable> <gradle.executable>gradlew.bat</gradle.executable>
</properties> </properties>
</profile> </profile>
<profile>
<id>full</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<dependencies>
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>1.0b3</version>
<exclusions>
<exclusion>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-nodeps</artifactId>
<version>1.8.1</version>
</dependency>
<dependency>
<groupId>org.tigris.antelope</groupId>
<artifactId>antelopetasks</artifactId>
<version>3.2.10</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>set-up-maven-properties</id>
<phase>prepare-package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<exportAntProperties>true</exportAntProperties>
<target>
<taskdef resource="net/sf/antcontrib/antcontrib.properties" />
<taskdef name="stringutil" classname="ise.antelope.tasks.StringUtilTask" />
<var name="version-type" value="${project.version}" />
<propertyregex property="version-type" override="true" input="${version-type}" regexp=".*\.(.*)" replace="\1" />
<propertyregex property="version-type" override="true" input="${version-type}" regexp="(M)\d+" replace="MILESTONE" />
<propertyregex property="version-type" override="true" input="${version-type}" regexp="(RC)\d+" replace="MILESTONE" />
<propertyregex property="version-type" override="true" input="${version-type}" regexp="BUILD-(.*)" replace="SNAPSHOT" />
<var name="github-tag" value="v${project.version}" />
<propertyregex property="github-tag" override="true" input="${github-tag}" regexp=".*SNAPSHOT" replace="master" />
</target>
</configuration>
</execution>
<execution>
<id>package-docs-zip</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<zip destfile="${project.build.directory}/${project.artifactId}-${project.version}-docs.zip">
<zipfileset src="build/libs/${project.artifactId}-${project.version}-javadoc.jar" prefix="api" />
<zipfileset dir="${project.build.directory}/generated-docs" prefix="reference" />
</zip>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.3</version>
<executions>
<execution>
<id>generate-html-documentation</id>
<phase>prepare-package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
</configuration>
</execution>
<execution>
<id>generate-pdf-documentation</id>
<phase>prepare-package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>pdf</backend>
</configuration>
</execution>
</executions>
<configuration>
<attributes>
<version-type>${version-type}</version-type>
<version>${project.version}</version>
</attributes>
</configuration>
<dependencies>
<dependency>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctorj-pdf</artifactId>
<version>1.5.0-alpha.11</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>attach-zip</id>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/${project.artifactId}-${project.version}-docs.zip</file>
<type>zip</type>
<classifier>docs</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles> </profiles>
</project> </project>
[[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 <<reacting-to-other-plugins, reacting to other plugins>>.
\ No newline at end of file
= 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
[[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]
----
[[managing-dependencies]]
== Managing dependencies
When you apply the {dependency-management-plugin}[`io.spring.dependency-management`]
plugin, Spring Boot's plugin will
automatically <<reacting-to-other-plugins-dependency-management,import the
`spring-boot-dependencies` bom>> from the version of Spring Boot that you are using.
This provides a similar dependency management experience to the one that's enjoyed by
Maven users. For example, it allows you to omit version numbers when declaring
dependencies that are managed in the bom. To make use of this functionality, simply
declare dependencies in the usual way but omit the version number:
[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
[[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
[[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.
[[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.
[[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.
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'
buildscript {
repositories {
maven { url 'https://repo.spring.io/libs-snapshot' }
}
dependencies {
classpath files(pluginClasspath.split(','))
}
}
apply plugin: 'org.springframework.boot'
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)
}
}
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[]
buildscript {
dependencies {
classpath files(pluginClasspath.split(','))
}
}
apply plugin: 'org.springframework.boot'
apply plugin: 'java'
// tag::build-info[]
springBoot {
buildInfo()
}
// end::build-info[]
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[]
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']
}
}
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[]
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[]
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[]
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[]
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[]
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[]
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[]
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[]
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[]
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[]
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[]
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
}
}
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
}
}
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
}
}
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
}
}
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
}
}
/* 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;
}
/*
* 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");
}
}
/*
* 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);
}
}
}
/*
* 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");
}
}
/*
* 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");
}
}
}
/*
* 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");
}
}
/*
* 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");
}
}
...@@ -18,10 +18,9 @@ package org.springframework.boot.gradle.testkit; ...@@ -18,10 +18,9 @@ package org.springframework.boot.gradle.testkit;
import java.io.File; import java.io.File;
import java.io.FileReader; import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
...@@ -41,6 +40,7 @@ import org.xml.sax.InputSource; ...@@ -41,6 +40,7 @@ import org.xml.sax.InputSource;
import org.springframework.asm.ClassVisitor; import org.springframework.asm.ClassVisitor;
import org.springframework.boot.loader.tools.LaunchScript; import org.springframework.boot.loader.tools.LaunchScript;
import org.springframework.util.FileCopyUtils;
/** /**
* A {@link TestRule} for running a Gradle build using {@link GradleRunner}. * A {@link TestRule} for running a Gradle build using {@link GradleRunner}.
...@@ -143,9 +143,10 @@ public class GradleBuild implements TestRule { ...@@ -143,9 +143,10 @@ public class GradleBuild implements TestRule {
} }
public GradleRunner prepareRunner(String... arguments) throws IOException { public GradleRunner prepareRunner(String... arguments) throws IOException {
Files.copy(new File(this.script).toPath(), String scriptContent = FileCopyUtils.copyToString(new FileReader(this.script))
new File(this.projectDir, "build.gradle").toPath(), .replace("{version}", getBootVersion());
StandardCopyOption.REPLACE_EXISTING); FileCopyUtils.copy(scriptContent,
new FileWriter(new File(this.projectDir, "build.gradle")));
GradleRunner gradleRunner = GradleRunner.create().withProjectDir(this.projectDir) GradleRunner gradleRunner = GradleRunner.create().withProjectDir(this.projectDir)
.forwardOutput(); .forwardOutput();
List<String> allArguments = new ArrayList<String>(); List<String> allArguments = new ArrayList<String>();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment