The plugin can create an OCI image from a jar or war file using Cloud Native Buildpacks (CNB).
Images can be built using the bootBuildImage
task.
The task is automatically created when the java
or war
plugin is applied and is an instance of BootBuildImage
.
The bootBuildImage
task requires access to a Docker daemon.
By default, it will communicate with a Docker daemon over a local connection.
This works with Docker Engine on all supported platforms without configuration.
Environment variables can be set to configure the bootBuildImage
task to use an alternative local or remote connection.
The following table shows the environment variables and their values:
DOCKER_HOST
URL containing the host and port for the Docker daemon - for example tcp://192.168.99.100:2376
DOCKER_TLS_VERIFY
Enable secure HTTPS protocol when set to 1
(optional)
DOCKER_CERT_PATH
Path to certificate and key files for HTTPS (required if DOCKER_TLS_VERIFY=1
, ignored otherwise)
Docker daemon connection information can also be provided using docker
properties in the plugin configuration.
The following table summarizes the available properties:
URL containing the host and port for the Docker daemon - for example tcp://192.168.99.100:2376
tlsVerify
Enable secure HTTPS protocol when set to true
(optional)
certPath
Path to certificate and key files for HTTPS (required if tlsVerify
is true
, ignored otherwise)
bindHostToBuilder
When true
, the value of the host
property will be provided to the container that is created for the CNB builder (optional)
If the Docker images specified by the builder
or runImage
properties are stored in a private Docker image registry that requires authentication, the authentication credentials can be provided using docker.builderRegistry
properties.
If the generated Docker image is to be published to a Docker image registry, the authentication credentials can be provided using docker.publishRegistry
properties.
Properties are provided for user authentication or identity token authentication.
Consult the documentation for the Docker registry being used to store images for further information on supported authentication methods.
The following table summarizes the available properties for docker.builderRegistry
and docker.publishRegistry
:
email
E-mail address for the Docker image registry user. Optional for user authentication.
token
Identity token for the Docker image registry user. Required for token authentication.
The plugin invokes a builder to orchestrate the generation of an image.
The builder includes multiple buildpacks that can inspect the application to influence the generated image.
By default, the plugin chooses a builder image.
The name of the generated image is deduced from project properties.
Task properties can be used to configure how the builder should operate on the project.
The following table summarizes the available properties and their default values:
--builder
Name of the Builder image to use.
paketobuildpacks/builder:base
or paketobuildpacks/builder:tiny
when GraalVM Native Image plugin is applied.
runImage
--runImage
Name of the run image to use.
No default value, indicating the run image specified in Builder metadata should be used.
imageName
--imageName
Image name for the generated image.
docker.io/library/${project.name}:${project.version}
pullPolicy
--pullPolicy
Policy used to determine when to pull the builder and run images from the registry.
Acceptable values are ALWAYS
, NEVER
, and IF_NOT_PRESENT
.
ALWAYS
environment
Environment variables that should be passed to the builder.
Empty or ['BP_NATIVE_IMAGE': 'true']
when GraalVM Native Image plugin is applied.
buildpacks
Buildpacks that the builder should use when building the image.
Only the specified buildpacks will be used, overriding the default buildpacks included in the builder.
Buildpack references must be in one of the following forms:
Volume bind mounts that should be mounted to the builder container when building the image.
The bindings will be passed unparsed and unvalidated to Docker when creating the builder container.
Bindings must be in one of the following forms:
buildCache
A cache containing layers created by buildpacks and used by the image building process.
A named volume in the Docker daemon, with a name derived from the image name.
launchCache
A cache containing layers created by buildpacks and used by the image launching process.
A named volume in the Docker daemon, with a name derived from the image name.
The plugin detects the target Java compatibility of the project using the JavaPlugin’s targetCompatibility
property.
When using the default Paketo builder and buildpacks, the plugin instructs the buildpacks to install the same Java version.
You can override this behaviour as shown in the builder configuration examples.
If you need to customize the builder used to create the image or the run image used to launch the built image, configure the task as shown in the following example:
Groovy
tasks.named("bootBuildImage") {
builder = "mine/java-cnb-builder"
runImage = "mine/java-cnb-run"
tasks.named<BootBuildImage>("bootBuildImage") {
builder.set("mine/java-cnb-builder")
runImage.set("mine/java-cnb-run")
This configuration will use a builder image with the name mine/java-cnb-builder
and the tag latest
, and the run image named mine/java-cnb-run
and the tag latest
.
The builder and run image can be specified on the command line as well, as shown in this example:
$ gradle bootBuildImage --builder=mine/java-cnb-builder --runImage=mine/java-cnb-run
If the builder exposes configuration options, those can be set using the environment
property.
The following is an example of configuring the JVM version used by the Paketo Java buildpacks at build time:
Groovy
tasks.named("bootBuildImage") {
environment["BP_JVM_VERSION"] = "17"
tasks.named<BootBuildImage>("bootBuildImage") {
environment.set(environment.get() + mapOf("BP_JVM_VERSION" to "17"))
If there is a network proxy between the Docker daemon the builder runs in and network locations that buildpacks download artifacts from, you will need to configure the builder to use the proxy.
When using the Paketo builder, this can be accomplished by setting the HTTPS_PROXY
and/or HTTP_PROXY
environment variables as show in the following example:
Groovy
tasks.named("bootBuildImage") {
environment["HTTP_PROXY"] = "http://proxy.example.com"
environment["HTTPS_PROXY"] = "https://proxy.example.com"
tasks.named<BootBuildImage>("bootBuildImage") {
environment.set(mapOf("HTTP_PROXY" to "http://proxy.example.com",
"HTTPS_PROXY" to "https://proxy.example.com"))
Paketo Java buildpacks configure the JVM runtime environment by setting the JAVA_TOOL_OPTIONS
environment variable.
The buildpack-provided JAVA_TOOL_OPTIONS
value can be modified to customize JVM runtime behavior when the application image is launched in a container.
Environment variable modifications that should be stored in the image and applied to every deployment can be set as described in the Paketo documentation and shown in the following example:
Groovy
tasks.named("bootBuildImage") {
environment["BPE_DELIM_JAVA_TOOL_OPTIONS"] = " "
environment["BPE_APPEND_JAVA_TOOL_OPTIONS"] = "-XX:+HeapDumpOnOutOfMemoryError"
tasks.named<BootBuildImage>("bootBuildImage") {
environment.set(mapOf(
"BPE_DELIM_JAVA_TOOL_OPTIONS" to " ",
"BPE_APPEND_JAVA_TOOL_OPTIONS" to "-XX:+HeapDumpOnOutOfMemoryError"
By default, the image name is inferred from the name
and the version
of the project, something like docker.io/library/${project.name}:${project.version}
.
You can take control over the name by setting task properties, as shown in the following example:
Groovy
tasks.named("bootBuildImage") {
imageName = "example.com/library/${project.name}"
tasks.named<BootBuildImage>("bootBuildImage") {
imageName.set("example.com/library/${project.name}")
Note that this configuration does not provide an explicit tag so latest
is used.
It is possible to specify a tag as well, either using ${project.version}
, any property available in the build or a hardcoded version.
The image name can be specified on the command line as well, as shown in this example:
$ gradle bootBuildImage --imageName=example.com/library/my-app:v1
By default, the builder will use buildpacks included in the builder image and apply them in a pre-defined order.
An alternative set of buildpacks can be provided to apply buildpacks that are not included in the builder, or to change the order of included buildpacks.
When one or more buildpacks are provided, only the specified buildpacks will be applied.
The following example instructs the builder to use a custom buildpack packaged in a .tgz
file, followed by a buildpack included in the builder.
Groovy
tasks.named("bootBuildImage") {
buildpacks = ["file:///path/to/example-buildpack.tgz", "urn:cnb:builder:paketo-buildpacks/java"]
tasks.named<BootBuildImage>("bootBuildImage") {
buildpacks.set(listOf("file:///path/to/example-buildpack.tgz", "urn:cnb:builder:paketo-buildpacks/java"))
The generated image can be published to a Docker registry by enabling a publish
option.
If the Docker registry requires authentication, the credentials can be configured using docker.publishRegistry
properties.
If the Docker registry does not require authentication, the docker.publishRegistry
configuration can be omitted.
The registry that the image will be published to is determined by the registry part of the image name (docker.example.com
in these examples).
If docker.publishRegistry
credentials are configured and include a url
property, this value is passed to the registry but is not used to determine the publishing registry location.
tasks.named("bootBuildImage") {
imageName.set("docker.example.com/library/${project.name}")
publish = true
docker {
publishRegistry {
username = "user"
password = "secret"
tasks.named<BootBuildImage>("bootBuildImage") {
imageName.set("docker.example.com/library/${project.name}")
publish.set(true)
docker {
publishRegistry {
username.set("user")
password.set("secret")
The CNB builder caches layers that are used when building and launching an image.
By default, these caches are stored as named volumes in the Docker daemon with names that are derived from the full name of the target image.
If the image name changes frequently, for example when the project version is used as a tag in the image name, then the caches can be invalidated frequently.
The cache volumes can be configured to use alternative names to give more control over cache lifecycle as shown in the following example:
Groovy
tasks.named("bootBuildImage") {
buildCache {
volume {
name = "cache-${rootProject.name}.build"
launchCache {
volume {
name = "cache-${rootProject.name}.launch"
The plugin can communicate with the Docker daemon provided by minikube instead of the default local connection.
On Linux and macOS, environment variables can be set using the command eval $(minikube docker-env)
after minikube has been started.
The plugin can also be configured to use the minikube daemon by providing connection details similar to those shown in the following example:
Groovy
tasks.named("bootBuildImage") {
docker {
host = "tcp://192.168.99.100:2376"
tlsVerify = true
certPath = "/home/user/.minikube/certs"
tasks.named<BootBuildImage>("bootBuildImage") {
docker {
host.set("tcp://192.168.99.100:2376")
tlsVerify.set(true)
certPath.set("/home/user/.minikube/certs")
The plugin can communicate with a podman container engine.
The plugin can be configured to use podman local connection by providing connection details similar to those shown in the following example:
Groovy
tasks.named("bootBuildImage") {
docker {
host = "unix:///run/user/1000/podman/podman.sock"
bindHostToBuilder = true
tasks.named<BootBuildImage>("bootBuildImage") {
docker {
host.set("unix:///run/user/1000/podman/podman.sock")
bindHostToBuilder.set(true)
If the builder or run image are stored in a private Docker registry that supports user authentication, authentication details can be provided using docker.builderRegistry
properties as shown in the following example:
Groovy
tasks.named("bootBuildImage") {
docker {
builderRegistry {
username = "user"
password = "secret"
url = "https://docker.example.com/v1/"
email = "
[email protected]"
password.set("secret")
url.set("https://docker.example.com/v1/")
email.set("[email protected]")
If the builder or run image is stored in a private Docker registry that supports token authentication, the token value can be provided using docker.builderRegistry
as shown in the following example:
Groovy
tasks.named("bootBuildImage") {
docker {
builderRegistry {
token = "9cbaf023786cd7..."
To publish your Spring Boot jar or war, add it to the publication using the artifact
method on MavenPublication
.
Pass the task that produces that artifact that you wish to publish to the artifact
method.
For example, to publish the artifact produced by the default bootJar
task:
Groovy
publishing {
publications {
bootJava(MavenPublication) {
artifact tasks.named("bootJar")
repositories {
maven {
url 'https://repo.example.com'
When the 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.
To use the application
plugin, its mainClassName
property must be configured with the name of your application’s main class.
The bootRun
task is an instance of BootRun
which is a JavaExec
subclass.
As such, all of the 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 the main source set’s output.
The main class can also be configured explicitly using the task’s main
property:
Groovy
tasks.named("bootRun") {
mainClass = 'com.example.ExampleApplication'
Alternatively, the main class name can be configured project-wide using the mainClass
property of the Spring Boot DSL:
Groovy
springBoot {
mainClass = 'com.example.ExampleApplication'
By default, bootRun
will configure the JVM to optimize its launch for faster startup during development.
This behavior can be disabled by using the optimizedLaunch
property, as shown in the following example:
Groovy
tasks.named("bootRun") {
optimizedLaunch = false
If the application
plugin has been applied, its mainClass
property must be configured and can be used for the same purpose:
Groovy
application {
mainClass = 'com.example.ExampleApplication'
Like all JavaExec
tasks, arguments can be passed into bootRun
from the command line using --args='<arguments>'
when using Gradle 4.9 or later.
For example, to run your application with a profile named dev
active the following command can be used:
$ ./gradlew bootRun --args='--spring.profiles.active=dev'
See the javadoc for JavaExec.setArgsString
for further details.
Since bootRun
is a standard JavaExec
task, system properties can be passed to the application’s JVM by specifying them in the build script.
To make that value of a system property to be configurable set its value using a project property.
To allow a project property to be optional, reference it using findProperty
.
Doing so also allows a default value to be provided using the ?:
Elvis operator, as shown in the following example:
Groovy
tasks.named("bootRun") {
systemProperty 'com.example.property', findProperty('example') ?: 'default'
tasks.named<BootRun>("bootRun") {
systemProperty("com.example.property", findProperty("example") ?: "default")
The preceding example sets that com.example.property
system property to the value of the example
project property.
If the example
project property has not been set, the value of the system property will be default
.
Gradle allows project properties to be set in a variety of ways, including on the command line using the -P
flag, as shown in the following example:
$ ./gradlew bootRun -Pexample=custom
The preceding example sets the value of the example
project property to custom
.
bootRun
will then use this as the value of the com.example.property
system property.
If devtools has been added to your project it will automatically monitor your application’s classpath for changes.
Note that modified files need to be recompiled for the classpath to update in order to trigger reloading with devtools.
For more details on using devtools, refer to this section of the reference documentation.
Alternatively, you can configure bootRun
such that your application’s static resources are loaded from their source location:
Groovy
tasks.named("bootRun") {
sourceResources sourceSets.main
Spring AOT is a process that analyzes your code at build-time in order to generate an optimized version of it.
It is most often used to help generate GraalVM native images.
The Spring Boot Gradle plugin provides tasks that can be used to perform AOT processing on both application and test code.
The tasks are configured automatically when the GraalVM Native Image plugin is applied:
Groovy
plugins {
id 'org.springframework.boot' version '3.0.6'
id 'org.graalvm.buildtools.native' version '0.9.21'
id 'java'
plugins {
id("org.springframework.boot") version "3.0.6"
id("org.graalvm.buildtools.native") version "0.9.21"
Based on your @SpringBootApplication
-annotated main class, the processAot
task generates a persistent view of the beans that are going to be contributed at runtime in a way that bean instantiation is as straightforward as possible.
Additional post-processing of the factory is possible using callbacks.
For instance, these are used to generate the necessary reflection configuration that GraalVM needs to initialize the context in a native image.
As the BeanFactory
is fully prepared at build-time, conditions are also evaluated.
This has an important difference compared to what a regular Spring Boot application does at runtime.
For instance, if you want to opt-in or opt-out for certain features, you need to configure the environment used at build time to do so.
To this end, the processAot
task is a JavaExec
task and can be configured with environment variables, system properties, and arguments as needed.
The nativeCompile
task of the GraalVM Native Image plugin is automatically configured to use the output of the processAot
task.
The AOT engine can be applied to JUnit 5 tests that use Spring’s Test Context Framework.
Suitable tests are processed by the processTestAot
task to generate ApplicationContextInitialzer
code.
As with application AOT processing, the BeanFactory
is fully prepared at build-time.
As with processAot
, the processTestAot
task is JavaExec
subclass and can be configured as needed to influence this processing.
The nativeTest
task of the GraalVM Native Image plugin is automatically configured to use the output of the processAot
and processTestAot
tasks.
Spring Boot Actuator’s info
endpoint automatically publishes information about your build in the presence of a META-INF/build-info.properties
file.
A BuildInfo
task is provided to generate this file.
The easiest way to use the task is through the plugin’s DSL:
Groovy
springBoot {
buildInfo()
This will configure a BuildInfo
task named bootBuildInfo
and, if it exists, make the Java plugin’s classes
task depend upon it.
The task’s destination 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:
To exclude any of the default properties from the generated build information, add its name to the excludes.
For example, the time
property can be excluded as follows:
Groovy
springBoot {
buildInfo {
excludes = ['time']
The default value for build.time
is the instant at which the project is being built.
A side-effect of this is that the task will never be up-to-date.
As a result, builds will take longer as more tasks, including the project’s tests, will have to be executed.
Another side-effect is that the task’s output will always change and, therefore, the build will not be truly repeatable.
If you value build performance or repeatability more highly than the accuracy of the build.time
property, exclude the time
property as shown in the preceding example.
Additional properties can also be added to the build information:
Groovy
springBoot {
buildInfo {
properties {
additional = [
'a': 'alpha',
'b': 'bravo'
When another plugin is applied the Spring Boot plugin reacts by making various changes to the project’s configuration.
This section describes those changes.
When Gradle’s java
plugin is applied to a project, the Spring Boot plugin:
Creates a 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
Configures the assemble
task to depend on the bootJar
task.
Configures the jar
task to use plain
as the convention for its archive classifier.
Creates a BootBuildImage
task named bootBuildImage
that will create a OCI image using a buildpack.
Creates a BootRun
task named bootRun
that can be used to run your application.
Creates a configuration named bootArchives
that contains the artifact produced by the bootJar
task.
Creates a configuration named developmentOnly
for dependencies that are only required at development time, such as Spring Boot’s Devtools, and should not be packaged in executable jars and wars.
Creates a configuration named productionRuntimeClasspath
. It is equivalent to runtimeClasspath
minus any dependencies that only appear in the developmentOnly
configuration.
Configures any JavaCompile
tasks with no configured encoding to use UTF-8
.
Configures any JavaCompile
tasks to use the -parameters
compiler argument.
Aligns the Kotlin version used in Spring Boot’s dependency management with the version of the plugin.
This is achieved by setting the kotlin.version
property with a value that matches the version of the Kotlin plugin.
Configures any KotlinCompile
tasks to use the -java-parameters
compiler argument.
Creates a 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
.
Configures the assemble
task to depend on the bootWar
task.
Configures the war
task to use plain
as the convention for its archive classifier.
Configures the bootArchives
configuration to contain the artifact produced by the bootWar
task.
Creates a CreateStartScripts
task named bootStartScripts
that will create scripts that launch the artifact in the bootArchives
configuration using java -jar
.
The task is configured to use the applicationDefaultJvmArgs
property as a convention for its defaultJvmOpts
property.
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.
Configures the bootRun
task to use the mainClassName
property as a convention for its main
property.
Configures the bootRun
task to use the applicationDefaultJvmArgs
property as a convention for its jvmArgs
property.
Configures the bootJar
task to use the mainClassName
property as a convention for the Start-Class
entry in its manifest.
Configures the bootWar
task to use the mainClassName
property as a convention for the Start-Class
entry in its manifest.
Registers a ProcessAot
task named processAot
that will generate AOT-optimized source for the application in the aot
source set.
Configures the Java compilation and process resources tasks for the aot
source set to depend upon processAot
.
Registers a ProcessTestAot
task named processTestAot
that will generated AOT-optimized source for the application’s tests in the aotTest
source set.
Configures the Java compilation and process resources tasks for the aotTest
source set to depend upon processTestAot
.
Adds the output of the aot
source set to the classpath of the main
GraalVM native binary.
Adds the output of the aotTest
source set to the classpath of the test
GraalVM native binary.
Configures the GraalVM extension to disable Toolchain detection.
Configures each GraalVM native binary to require GraalVM 22.3 or later.
Configures the bootJar
task to include the reachability metadata produced by the collectReachabilityMetadata
task in its jar.
Configures the bootBuildImage
task to use paketobuildpacks/builder:tiny
as its builder and to set BP_NATIVE_IMAGE
to true
in its environment.