67. Spring Boot Gradle plugin

The Spring Boot Gradle Plugin provides Spring Boot support in Gradle, allowing you to package executable jar or war archives, run Spring Boot applications and use the dependency management provided by spring-boot-dependencies.

67.1 Including the plugin

To use the Spring Boot Gradle Plugin simply include a buildscript dependency and apply the spring-boot plugin:

buildscript {
    repositories {
        maven { url 'https://repo.spring.io/snapshot' }
        maven { url 'https://repo.spring.io/milestone' }
    }
    dependencies {
        classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.5.20.BUILD-SNAPSHOT''
    }
}
apply plugin: 'org.springframework.boot'

67.2 Gradle dependency management

The spring-boot plugin automatically applies the 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:

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.thymeleaf:thymeleaf-spring4")
    compile("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect")
}
[Note]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.

To learn more about the capabilities of the Dependency Management Plugin, please refer to its documentation.

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

[Tip]Tip

Check Section 67.6, “Repackage configuration” for a full list of configuration options.

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 the war plugin’s providedRuntime configuration, e.g.:

...
apply plugin: 'war'

war {
    baseName = 'myapp'
    version =  '0.5.0'
}

repositories {
    jcenter()
    maven { url "https://repo.spring.io/libs-snapshot" }
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
    ...
}
[Tip]Tip

See the “Section 86.1, “Create a deployable war file”” section for more details on how to create a deployable war file.

67.4 Running a project in-place

To run a project in place without building a jar first you can use the “bootRun” task:

$ gradle bootRun

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

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.

67.5 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):

springBoot {
    backupSource = false
}

67.6 Repackage configuration

The plugin adds a bootRepackage task which you can also configure directly, e.g.:

bootRepackage {
    mainClass = 'demo.Application'
}

The following configuration options are available:

NameDescription

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.

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

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.

67.7.1 Configuration options

The following configuration options are available:

NameDescription

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

67.7.2 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:

NameDescriptionExecutable

JAR

Regular executable JAR layout.

Yes

WAR

Executable 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 PropertiesLauncher.

Yes

MODULE

Bundle dependencies (excluding those with provided scope) and project resources.

No

NONE

Bundle all dependencies and project resources.

No

67.7.3 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:

buildscript {
	repositories {
		mavenCentral()
	}
	dependencies {
		classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.20.BUILD-SNAPSHOT")
		classpath("com.example:custom-layout:1.0.0")
	}
}

springBoot {
	layoutFactory = new com.example.CustomLayoutFactory()
}
[Note]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.

67.8 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:

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.

67.9 Publishing artifacts to a Maven repository using Gradle

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.

67.9.1 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 for further information.

uploadArchives {
    repositories {
        mavenDeployer {
            pom {
                project {
                    parent {
                        groupId "org.springframework.boot"
                        artifactId "spring-boot-starter-parent"
                        version "1.5.20.BUILD-SNAPSHOT"
                    }
                }
            }
        }
    }
}

67.9.2 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 Gradle User Guide for further information.

uploadArchives {
    repositories {
        mavenDeployer {
            pom {
                project {
                    dependencyManagement {
                        dependencies {
                            dependency {
                                groupId "org.springframework.boot"
                                artifactId "spring-boot-dependencies"
                                version "1.5.20.BUILD-SNAPSHOT"
                                type "pom"
                                scope "import"
                            }
                        }
                    }
                }
            }
        }
    }
}