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.2 (or better).
Note
|
Refer to the {spring-boot-maven-plugin-site}/[Spring Boot Maven Plugin Site] for complete plugin documentation. |
To use the Spring Boot Maven Plugin simply include the appropriate XML in the plugins
section of your pom.xml
<?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:
$ 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:
$ 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:
<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>
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:
<?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:
$ 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:
<?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>
Tip
|
See the “[howto-create-a-deployable-war-file]” section for more details on how to create a deployable war file. |
Advanced configuration options and examples are available in the {spring-boot-maven-plugin-site}/[plugin info page].
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.
To use the Spring Boot Gradle Plugin simply include a buildscript
dependency and apply
the spring-boot
plugin:
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:
buildscript {
repositories {
maven.url "http://repo.spring.io/snapshot"
maven.url "http://repo.spring.io/milestone"
}
// ...
}
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:
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.
|
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:
dependencies {
compile("org.thymeleaf:thymeleaf-spring4:2.1.1.RELEASE")
}
If is possible to customize the versions used by the ResolutionStrategy
if you need
to deviate from Spring Boot’s “blessed” dependencies. Alternative version metadata
is consulted using the versionManagement
configuration. For example:
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:
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.
Gradle handles “exclude rules” in a slightly different way to Maven which can cause unexpected results when using the starter POMs. Specifically, exclusions declared on a dependency will not be applied when the dependency can be reached through a different path. For example, if a starter POM declares the following:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.5.RELEASE</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0.5.RELEASE</version>
</dependency>
</dependencies>
The commons-logging
jar will not be excluded by Gradle because it is pulled in
transitively via spring-context
(spring-context
→ spring-core
→ commons-logging
)
which does not have an exclusion
element.
To ensure that correct exclusions are actually applied, the Spring Boot Gradle plugin will
automatically add exclusion rules. All exclusions defined in the
spring-boot-dependencies
POM and implicit rules for the “starter” POMs will be added.
If you don’t want exclusion rules automatically applied you can use the following configuration:
springBoot {
applyExcludeRules=false
}
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:
$ 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:
...
apply plugin: 'war'
war {
baseName = 'myapp'
version = '0.5.0'
}
repositories {
jcenter()
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")
...
}
Tip
|
See the “[howto-create-a-deployable-war-file]” section for more details on how to create a deployable war file. |
To run a project in place without building a jar first you can use the “bootRun” task:
$ 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.
Note
|
Making static classpath resources reloadable means that bootRun does not use the
output of the processResources task. When invoked using bootRun your application will
use the resources in their unprocessed form.
|
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):
springBoot {
backupSource = false
}
The plugin adds a bootRepackage
task which you can also configure directly, e.g.:
bootRepackage {
mainClass = 'demo.Application'
}
The following configuration options are available:
Name | Description |
---|---|
|
Boolean flag to switch the repackager off (sometimes useful if you want the other Boot features but not this one) |
|
The main class that should be run. If not specified the |
|
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, it’s best to use an extension to define the executable archive. |
|
The name or value of the |
|
The name of the custom configuration whuch is used to populate the nested lib directory (without specifying this you get all compile and runtime dependencies). |
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.
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
.
configurations {
mycustomconfiguration.exclude group: 'log4j'
}
dependencies {
mycustomconfiguration configurations.runtime
}
The configuration that we are referring to in BootRepackage
is a normal
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.
The following configuration options are available:
Name | Description |
---|---|
|
The main class that should be run by the executable archive. |
|
The name of the provided configuration (defaults to |
|
If the original source archive should be backed-up before being repackaged (defaults
to |
|
The name of the custom configuration. |
|
The type of archive, corresponding to how the dependencies are laid out inside (defaults to a guess based on the archive type). |
|
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. |
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:
jar.enabled = false
bootRepackage.enabled = false
Another option is to instruct the default bootRepackage
task to only work with a
default jar
task.
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:
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.
If you are 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.
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 for
further information.
uploadArchives {
repositories {
mavenDeployer {
pom {
project {
parent {
groupId "org.springframework.boot"
artifactId "spring-boot-starter-parent"
version "{spring-boot-version}"
}
}
}
}
}
}
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
Gradle User Guide for
further information.
uploadArchives {
repositories {
mavenDeployer {
pom {
project {
dependencyManagement {
dependencies {
dependency {
groupId "org.springframework.boot"
artifactId "spring-boot-dependencies"
version "{spring-boot-version}"
type "pom"
scope "import"
}
}
}
}
}
}
}
}
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 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.
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.
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
.
If you don’t use Repackager.setMainClass()
to specify a main class, the repackager will
use 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.
Here is a typical example repackage:
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(new Library(nestedFile, LibraryScope.COMPILE));
}
});
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 executable
jar format are covered in the appendix.
If you have specific build-related questions you can check out the “how-to” guides.