[[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.2 (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>
----

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].



[[build-tool-plugins-gradle-plugin]]
== Spring Boot Gradle plugin
The {spring-boot-gradle-plugin}[Spring Boot Gradle Plugin] provides Spring Boot support
in Gradle, allowing you to package executable jar or war archives, run Spring Boot
applications and use the dependency management provided by `spring-boot-dependencies`.
It requires Gradle 3.4 or later. Please refer to the {spring-boot-gradle-plugin}[plugin's
documentation] to learn more.



[[build-tool-plugins-antlib]]
== Spring Boot AntLib module
The Spring Boot AntLib module provides basic Spring Boot support for Apache Ant. You can
use the module to create executable jars. To use the module you need to declare an
additional `spring-boot` namespace in your `build.xml`:

[source,xml,indent=0]
----
	<project xmlns:ivy="antlib:org.apache.ivy.ant"
		xmlns:spring-boot="antlib:org.springframework.boot.ant"
		name="myapp" default="build">
		...
	</project>
----

You'll need to remember to start Ant using the `-lib` option, for example:

[indent=0,subs="verbatim,quotes,attributes"]
----
	$ ant -lib <folder containing spring-boot-antlib-{spring-boot-version}.jar>
----

TIP: The "`Using Spring Boot`" section includes a more complete example of
<<using-spring-boot.adoc#using-boot-ant, using Apache Ant with `spring-boot-antlib`>>


=== Spring Boot Ant tasks
Once the `spring-boot-antlib` namespace has been declared, the following additional
tasks are available.



==== spring-boot:exejar
The `exejar` task can be used to creates a Spring Boot executable jar. The following
attributes are supported by the task:

[cols="1,2,2"]
|====
|Attribute |Description |Required

|`destfile`
|The destination jar file to create
|Yes

|`classes`
|The root directory of Java class files
|Yes

|`start-class`
|The main application class to run
|No _(default is first class found declaring a `main` method)_
|====

The following nested elements can be used with the task:

[cols="1,4"]
|====
|Element |Description

|`resources`
|One or more {ant-manual}/Types/resources.html#collection[Resource Collections]
describing a set of {ant-manual}/Types/resources.html[Resources] that should be added to
the content of the created +jar+ file.

|`lib`
|One or more {ant-manual}/Types/resources.html#collection[Resource Collections]
that should be added to the set of jar libraries that make up the runtime dependency
classpath of the application.
|====



==== Examples
.Specify +start-class+
[source,xml,indent=0]
----
	<spring-boot:exejar destfile="target/my-application.jar"
			classes="target/classes" start-class="com.foo.MyApplication">
		<resources>
			<fileset dir="src/main/resources" />
		</resources>
		<lib>
			<fileset dir="lib" />
		</lib>
	</spring-boot:exejar>
----

.Detect +start-class+
[source,xml,indent=0]
----
	<exejar destfile="target/my-application.jar" classes="target/classes">
		<lib>
			<fileset dir="lib" />
		</lib>
	</exejar>
----



=== spring-boot:findmainclass
The `findmainclass` task is used internally by `exejar` to locate a class declaring a
`main`. You can also use this task directly in your build if needed. The following
attributes are supported

[cols="1,2,2"]
|====
|Attribute |Description |Required

|`classesroot`
|The root directory of Java class files
|Yes _(unless `mainclass` is specified)_

|`mainclass`
|Can be used to short-circuit the `main` class search
|No

|`property`
|The Ant property that should be set with the result
|No _(result will be logged if unspecified)_
|====



==== Examples
.Find and log
[source,xml,indent=0]
----
	<findmainclass classesroot="target/classes" />
----

.Find and set
[source,xml,indent=0]
----
	<findmainclass classesroot="target/classes" property="main-class" />
----

.Override and set
[source,xml,indent=0]
----
	<findmainclass mainclass="com.foo.MainClass" property="main-class" />
----



[[build-tool-plugins-other-build-systems]]
== Supporting other build systems
If you want to use a build tool other than Maven, Gradle or Ant, 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(new 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.
