
Refactor and rework several areas of the Gradle plugin: - Refactor package structure into functional areas and configure each area separately via a new PluginFeatures interface. - Convert BootRunTask to extend RunTask rather than attempting to find existing RunTasks. - Simplify agent integration by no longer needing specific BootRunTask code. - Update the repackage task to consider the `mainClassName` property in addition to `springBoot.mainClass`. - Automatically set `mainClassName` when calling `run` or `runBoot` from `springBoot.mainClass` if there is one. - Ensure that explicitly defined `main` options on JavaExec tasks always take precedence. Fixes gh-547, gh-820, gh-886, gh-912
542 lines
18 KiB
Plaintext
542 lines
18 KiB
Plaintext
[[build-tool-plugins]]
|
|
= Build tool plugins
|
|
|
|
[partintro]
|
|
--
|
|
Spring Boot provides build tool plugins for Maven and Gradle. The plugins offer a
|
|
variety of features, including the packaging of executable jars. This section provides
|
|
more details on both plugins, as well as some help should you need to extend an
|
|
unsupported build system. If you are just getting started, you might want to read
|
|
``<<using-spring-boot.adoc#using-boot-build-systems>>'' from the
|
|
<<using-spring-boot.adoc#using-boot>> section first.
|
|
--
|
|
|
|
|
|
|
|
[[build-tool-plugins-maven-plugin]]
|
|
== Spring Boot Maven plugin
|
|
The {spring-boot-maven-plugin-site}/[Spring Boot Maven Plugin] provides Spring Boot
|
|
support in Maven, allowing you to package executable jar or war archives and run an
|
|
application ``in-place''. To use it you must be using Maven 3 (or better).
|
|
|
|
NOTE: Refer to the {spring-boot-maven-plugin-site}/[Spring Boot Maven Plugin Site]
|
|
for complete plugin documentation.
|
|
|
|
|
|
|
|
[[build-tool-plugins-include-maven-plugin]]
|
|
=== Including the plugin
|
|
To use the Spring Boot Maven Plugin simply include the appropriate XML in the `plugins`
|
|
section of your `pom.xml`
|
|
|
|
[source,xml,indent=0,subs="verbatim,attributes"]
|
|
----
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
<modelVersion>4.0.0</modelVersion>
|
|
<!-- ... -->
|
|
<build>
|
|
<plugins>
|
|
<plugin>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
<version>{spring-boot-version}</version>
|
|
<executions>
|
|
<execution>
|
|
<goals>
|
|
<goal>repackage</goal>
|
|
</goals>
|
|
</execution>
|
|
</executions>
|
|
</plugin>
|
|
</plugins>
|
|
</build>
|
|
</project>
|
|
----
|
|
|
|
This configuration will repackage a jar or war that is built during the `package` phase of
|
|
the Maven lifecycle. The following example shows both the repackaged jar, as well as the
|
|
original jar, in the `target` directory:
|
|
|
|
[indent=0]
|
|
----
|
|
$ mvn package
|
|
$ ls target/*.jar
|
|
target/myproject-1.0.0.jar target/myproject-1.0.0.jar.original
|
|
----
|
|
|
|
|
|
If you don't include the `<execution/>` configuration as above, you can run the plugin on
|
|
its own (but only if the package goal is used as well). For example:
|
|
|
|
[indent=0]
|
|
----
|
|
$ mvn package spring-boot:repackage
|
|
$ ls target/*.jar
|
|
target/myproject-1.0.0.jar target/myproject-1.0.0.jar.original
|
|
----
|
|
|
|
If you are using a milestone or snapshot release you will also need to add appropriate
|
|
`pluginRepository` elements:
|
|
|
|
[source,xml,indent=0,subs="verbatim,attributes"]
|
|
----
|
|
<pluginRepositories>
|
|
<pluginRepository>
|
|
<id>spring-snapshots</id>
|
|
<url>http://repo.spring.io/snapshot</url>
|
|
</pluginRepository>
|
|
<pluginRepository>
|
|
<id>spring-milestones</id>
|
|
<url>http://repo.spring.io/milestone</url>
|
|
</pluginRepository>
|
|
</pluginRepositories>
|
|
----
|
|
|
|
|
|
|
|
[[build-tool-plugins-maven-packaging]]
|
|
=== Packaging executable jar and war files
|
|
Once `spring-boot-maven-plugin` has been included in your `pom.xml` it will automatically
|
|
attempt to rewrite archives to make them executable using the `spring-boot:repackage`
|
|
goal. You should configure your project to build a jar or war (as appropriate) using the
|
|
usual `packaging` element:
|
|
|
|
[source,xml,indent=0,subs="verbatim,attributes"]
|
|
----
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
<!-- ... -->
|
|
<packaging>jar</packaging>
|
|
<!-- ... -->
|
|
</project>
|
|
----
|
|
|
|
Your existing archive will be enhanced by Spring Boot during the `package` phase. 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 in the usual way. If you don't
|
|
specify a main class the plugin will search for a class with a
|
|
`public static void main(String[] args)` method.
|
|
|
|
To build and run a project artifact, you can type the following:
|
|
|
|
[indent=0]
|
|
----
|
|
$ mvn package
|
|
$ java -jar target/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 ``provided'', e.g:
|
|
|
|
[source,xml,indent=0,subs="verbatim,attributes"]
|
|
----
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
<!-- ... -->
|
|
<packaging>war</packaging>
|
|
<!-- ... -->
|
|
<dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-web</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
|
<scope>provided</scope>
|
|
</dependency>
|
|
<!-- ... -->
|
|
</dependencies>
|
|
</project>
|
|
----
|
|
|
|
Advanced configuration options and examples are available in the
|
|
{spring-boot-maven-plugin-site}/[plugin info page].
|
|
|
|
|
|
|
|
[[build-tool-plugins-gradle-plugin]]
|
|
== Spring Boot Gradle plugin
|
|
The Spring Boot Gradle Plugin provides Spring Boot support in Gradle, allowing you to
|
|
package executable jar or war archives, run Spring Boot applications and omit version
|
|
information from your `build.gradle` file for ``blessed'' dependencies.
|
|
|
|
|
|
|
|
[[build-tool-plugins-including-the-gradle-plugin]]
|
|
=== Including the plugin
|
|
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 {
|
|
dependencies {
|
|
classpath("org.springframework.boot:spring-boot-gradle-plugin:{spring-boot-version}")
|
|
}
|
|
}
|
|
apply plugin: 'spring-boot'
|
|
----
|
|
|
|
If you are using a milestone or snapshot release you will also need to add appropriate
|
|
`repositories` reference:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes"]
|
|
----
|
|
buildscript {
|
|
repositories {
|
|
maven.url "http://repo.spring.io/snapshot"
|
|
maven.url "http://repo.spring.io/milestone"
|
|
}
|
|
// ...
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[build-tool-plugins-gradle-dependencies-without-versions]]
|
|
=== Declaring dependencies without versions
|
|
The `spring-boot` plugin will register a custom Gradle `ResolutionStrategy` with your
|
|
build that allows you to omit version numbers when declaring dependencies to ``blessed''
|
|
artifacts. 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-spring4")
|
|
compile("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect")
|
|
}
|
|
----
|
|
|
|
NOTE: The version of the `spring-boot` gradle plugin that you declare determines the
|
|
actual versions of the ``blessed'' dependencies (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>>.
|
|
|
|
The `spring-boot` plugin will only supply a version where one is not specified. To
|
|
use a version of an artifact that differs from the one that the plugin would provide,
|
|
simply specify the version when you declare the dependency as you usually would. For
|
|
example:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes"]
|
|
----
|
|
dependencies {
|
|
compile("org.thymeleaf:thymeleaf-spring4:2.1.1.RELEASE")
|
|
}
|
|
----
|
|
|
|
|
|
|
|
[[build-tool-plugins-gradle-custom-version-management]]
|
|
==== Custom version management
|
|
If is possible to customize the versions used by the `ResolutionStrategy` if you need
|
|
to deviate from Spring Boot's ``blessed'' dependencies. Alternative version meta-data
|
|
is consulted using the `versionManagement` configuration. For example:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes"]
|
|
----
|
|
dependencies {
|
|
versionManagement("com.mycorp:mycorp-versions:1.0.0.RELEASE@properties")
|
|
compile("org.springframework.data:spring-data-hadoop")
|
|
}
|
|
----
|
|
|
|
Version information needs to be published to a repository as a `.properties` file. For
|
|
the above example `mycorp-versions.properties` file might contain the following:
|
|
|
|
[source,properties,indent=0,subs="verbatim,attributes"]
|
|
----
|
|
org.springframework.data\:spring-data-hadoop=2.0.0.RELEASE
|
|
----
|
|
|
|
The properties file takes precedence over Spring Boot's defaults, and can be used
|
|
to override version numbers if necessary.
|
|
|
|
|
|
|
|
[[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 `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.
|
|
|
|
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 a configuration
|
|
named "providedRuntime", e.g:
|
|
|
|
[source,groovy,indent=0,subs="verbatim,attributes"]
|
|
----
|
|
...
|
|
apply plugin: 'war'
|
|
|
|
war {
|
|
baseName = 'myapp'
|
|
version = '0.5.0'
|
|
}
|
|
|
|
repositories {
|
|
mavenCentral()
|
|
maven { url "http://repo.spring.io/libs-snapshot" }
|
|
}
|
|
|
|
configurations {
|
|
providedRuntime
|
|
}
|
|
|
|
dependencies {
|
|
compile("org.springframework.boot:spring-boot-starter-web")
|
|
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
|
|
...
|
|
}
|
|
----
|
|
|
|
|
|
[[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
|
|
----
|
|
|
|
Running this way makes your static classpath resources (i.e. in `src/main/resources` by
|
|
default) reloadable in the live application, which can be helpful at development time.
|
|
|
|
[[build-tool-plugins-gradle-repackage-configuration]]
|
|
=== Repackage configuration
|
|
The gradle plugin automatically extends your build script DSL with a `springBoot` element
|
|
for configuration. Simply 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-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
|
|
http://www.gradle.org/docs/current/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. If not specified the `mainClassName` project property
|
|
will be used or, if the no `mainClassName` id defined the archive will be searched for a
|
|
suitable class.
|
|
|
|
|`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).
|
|
|===
|
|
|
|
|
|
|
|
[[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 disables
|
|
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-other-build-systems]]
|
|
== Supporting other build systems
|
|
If you want to use a build tool other than Maven or Gradle, you will likely need to develop
|
|
your own plugin. Executable jars need to follow a specific format and certain entries need
|
|
to be written in an uncompressed form (see the
|
|
'<<appendix-executable-jar-format.adoc#executable-jar, executable jar format>>' section
|
|
in the appendix for details).
|
|
|
|
The Spring Boot Maven and Gradle plugins both make use of `spring-boot-loader-tools` to
|
|
actually generate jars. You are also free to use this library directly yourself if you
|
|
need to.
|
|
|
|
|
|
|
|
[[build-tool-plugins-repackaging-archives]]
|
|
=== Repackaging archives
|
|
To repackage an existing archive so that it becomes a self-contained executable archive
|
|
use `org.springframework.boot.loader.tools.Repackager`. The `Repackager` class takes a
|
|
single constructor argument that refers to an existing jar or war archive. Use one of the
|
|
two available `repackage()` methods to either replace the original file or write to a new
|
|
destination. Various settings can also be configured on the repackager before it is
|
|
run.
|
|
|
|
|
|
|
|
[[build-tool-plugins-nested-libraries]]
|
|
=== Nested libraries
|
|
When repackaging an archive you can include references to dependency files using the
|
|
`org.springframework.boot.loader.tools.Libraries` interface. We don't provide any
|
|
concrete implementations of `Libraries` here as they are usually build system specific.
|
|
|
|
If your archive already includes libraries you can use `Libraries.NONE`.
|
|
|
|
|
|
|
|
[[build-tool-plugins-find-a-main-class]]
|
|
=== Finding a main class
|
|
If you don't use `Repackager.setMainClass()` to specify a main class, the repackager will
|
|
use http://asm.ow2.org/[ASM] to read class files and attempt to find a suitable class
|
|
with a `public static void main(String[] args)` method. An exception is thrown if more
|
|
than one candidate is found.
|
|
|
|
|
|
|
|
[[build-tool-plugins-repackage-implementation]]
|
|
=== Example repackage implementation
|
|
Here is a typical example repackage:
|
|
|
|
[source,java,indent=0]
|
|
----
|
|
Repackager repackager = new Repackager(sourceJarFile);
|
|
repackager.setBackupSource(false);
|
|
repackager.repackage(new Libraries() {
|
|
@Override
|
|
public void doWithLibraries(LibraryCallback callback) throws IOException {
|
|
// Build system specific implementation, callback for each dependency
|
|
// callback.library(nestedFile, LibraryScope.COMPILE);
|
|
}
|
|
});
|
|
----
|
|
|
|
[[build-tool-plugins-whats-next]]
|
|
== What to read next
|
|
If you're interested in how the build tool plugins work you can
|
|
look at the {github-code}/spring-boot-tools[`spring-boot-tools`] module on GitHub. More
|
|
technical details of the <<appendix-executable-jar-format.adoc#executable-jar, executable
|
|
jar format>> are covered in the appendix.
|
|
|
|
If you have specific build-related questions you can check out the
|
|
`<<howto.adoc#howto, how-to>>' guides.
|