Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/spring-projects/spring-boot/llms.txt

Use this file to discover all available pages before exploring further.

Spring Boot’s Maven and Gradle plugins give you a streamlined path from source code to a runnable artifact. Whether you need a self-contained fat JAR, layered images for Docker, or a dependency-only library JAR, this guide walks you through the most common build tasks step by step.

Create an executable fat JAR

The spring-boot-maven-plugin and the Gradle bootJar task both produce a self-contained executable JAR that embeds your application classes together with all runtime dependencies.
If you inherit from spring-boot-starter-parent, declare the plugin without a version and run ./mvnw package:
pom.xml
<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
  </plugins>
</build>
Without the parent POM you must add an explicit <executions> block that binds the repackage goal:
pom.xml
<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <version>3.5.0</version>
      <executions>
        <execution>
          <goals>
            <goal>repackage</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>
./mvnw package
java -jar target/myapp-0.0.1-SNAPSHOT.jar
The executable JAR packages your application classes under BOOT-INF/classes and runtime dependencies under BOOT-INF/lib. This structure means the archive cannot be used directly as a library dependency by other projects.

Add build information to the Actuator /info endpoint

Both plugins can generate a build-info.properties file at build time. When the file is present, Spring Boot auto-configures a BuildProperties bean and the Actuator /actuator/info endpoint exposes the coordinates automatically.
Add an execution for the build-info goal:
pom.xml
<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <executions>
        <execution>
          <goals>
            <goal>build-info</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>
You can also enable build info exposure via configuration without repackaging, if the file is already on the classpath:
application.properties
management.info.build.enabled=true

Generate Git commit information

Both Maven and Gradle can write a git.properties file that surfaces repository metadata in the /actuator/info endpoint.
Add the Git Commit Id plugin (pre-configured in spring-boot-starter-parent):
pom.xml
<build>
  <plugins>
    <plugin>
      <groupId>io.github.git-commit-id</groupId>
      <artifactId>git-commit-id-maven-plugin</artifactId>
    </plugin>
  </plugins>
</build>
The commit timestamp in git.properties must follow the yyyy-MM-dd'T'HH:mm:ssZ format. Both plugins above use this format by default, which allows Jackson to control serialization through its standard date configuration.

Manage dependency versions with the Spring Boot BOM

Spring Boot ships a curated Bill of Materials (spring-boot-dependencies) that pins the versions of hundreds of common libraries. You do not need to specify individual versions for managed dependencies.
Inherit from spring-boot-starter-parent to get full BOM management:
pom.xml
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>3.5.0</version>
</parent>
To override a single managed version, set the corresponding property:
pom.xml
<properties>
  <jackson-bom.version>2.17.0</jackson-bom.version>
</properties>
Each Spring Boot release is designed and tested against a specific set of third-party library versions. Overriding managed versions may introduce compatibility issues. Override only when you have a specific reason, such as a security fix.

Customize the main class

By default the plugins detect the class with public static void main(String[] args) automatically. If your project has multiple candidates, specify the main class explicitly.
pom.xml
<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <configuration>
        <mainClass>com.example.MyApplication</mainClass>
      </configuration>
    </plugin>
  </plugins>
</build>

Use a Spring Boot application as a library dependency

Because executable JAR classes live under BOOT-INF/classes, other projects cannot find them on the classpath. The recommended solution is to extract shared code into a separate Maven/Gradle module. When that is not possible, configure the plugin to produce two artifacts: a standard JAR for use as a dependency and a classified executable JAR.
Apply an exec classifier to the executable archive so the default artifact remains a plain JAR:
pom.xml
<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <configuration>
        <classifier>exec</classifier>
      </configuration>
    </plugin>
  </plugins>
</build>

Exclude files from the non-executable library JAR

When you publish both an executable and a non-executable JAR, you may want to exclude application-specific files (such as application.yaml) from the library artifact.
pom.xml
<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
    <plugin>
      <artifactId>maven-jar-plugin</artifactId>
      <executions>
        <execution>
          <id>lib</id>
          <phase>package</phase>
          <goals>
            <goal>jar</goal>
          </goals>
          <configuration>
            <classifier>lib</classifier>
            <excludes>
              <exclude>application.yaml</exclude>
            </excludes>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

Configure layered JARs for efficient Docker images

Layered JARs split the executable archive into distinct layers (dependencies, Spring Boot loader, snapshot dependencies, application classes) so that Docker can cache unchanged layers between builds. This significantly reduces image push and pull times.
Layered JAR mode is enabled by default when you use the Spring Boot Maven plugin. To build the image with Cloud Native Buildpacks:
./mvnw spring-boot:build-image
To introspect the layers in the produced JAR:
java -Djarmode=tools -jar target/myapp-0.0.1-SNAPSHOT.jar list-layers

Generate a CycloneDX SBOM

The spring-boot-starter-parent POM pre-configures the CycloneDX Maven plugin. Declare it to activate SBOM generation at build time:
pom.xml
<build>
  <plugins>
    <plugin>
      <groupId>org.cyclonedx</groupId>
      <artifactId>cyclonedx-maven-plugin</artifactId>
    </plugin>
  </plugins>
</build>
Apply the CycloneDX Gradle plugin:
build.gradle
plugins {
    id 'org.cyclonedx.bom' version '3.0.0'
}

Multi-module project layout

In a multi-module build, place the Spring Boot plugin only on the module that produces the runnable application. Sibling library modules should use the standard jar packaging without the repackage goal, so they remain usable as dependencies.
my-project/
├── pom.xml                  # parent / BOM
├── my-app/
│   ├── pom.xml              # spring-boot-maven-plugin here
│   └── src/
└── my-library/
    ├── pom.xml              # no spring-boot-maven-plugin
    └── src/
Declare spring-boot-dependencies in the parent <dependencyManagement> section so all child modules share the same curated dependency versions without repeating version numbers.

Extract specific libraries when an executable JAR runs

Some libraries (for example, JRuby) expect to be available as a real file on disk rather than inside a JAR. Mark them for unpacking so the launcher extracts them to the system temporary directory before the JVM loads them.
pom.xml
<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <configuration>
        <requiresUnpack>
          <dependency>
            <groupId>org.jruby</groupId>
            <artifactId>jruby-complete</artifactId>
          </dependency>
        </requiresUnpack>
      </configuration>
    </plugin>
  </plugins>
</build>
Ensure your operating system is configured to retain files in the temporary directory while the application is running. Some Linux distributions periodically clean /tmp, which would delete unpacked JARs from a long-running process.

Build docs developers (and LLMs) love