Spring Boot provides a Gradle plugin with the id org.springframework.boot. It adds Gradle tasks that build and run Spring Boot applications. These tasks are used most often:
bootRun to run our Spring Boot application directly from the compiled classes (no jar file is needed).
bootJar to create an executable jar file. For an executable war file, we use bootWar.
The plugin has a few more tasks. For example, bootBuildImage creates a container image, bootBuildInfo creates a build-info.properties file, bootTestRun runs the application with the test classpath, and processAot is used for ahead-of-time processing (for example, for GraalVM native images).
plugins {
java
id("org.springframework.boot") version "4.1.2"
id("io.spring.dependency-management") version "1.1.7"
}
println(">>> EXECUTING SCRIPT: build.gradle.kts (Kotlin DSL)")
group = "com.logicbig.example"
version = "1.0-SNAPSHOT"
java {
sourceCompatibility = JavaVersion.VERSION_25
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
}
springBoot {
mainClass.set("com.logicbig.example.MainClass")
}
plugins {
id 'java'
id 'org.springframework.boot' version '4.1.2'
id 'io.spring.dependency-management' version '1.1.7'
}
println ">>> EXECUTING SCRIPT: build.gradle (Groovy DSL)"
group = 'com.logicbig.example'
version = '1.0-SNAPSHOT'
java {
sourceCompatibility = JavaVersion.VERSION_25
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webmvc'
}
springBoot {
mainClass.set('com.logicbig.example.MainClass')
}
Notes:
The org.springframework.boot plugin adds the boot* tasks. Its version is the Spring Boot version.
The io.spring.dependency-management plugin lets us write Spring Boot starters and other managed libraries without a version. When it is used together with the org.springframework.boot plugin, it automatically imports the spring-boot-dependencies BOM (bill of materials) for the same Spring Boot version as the plugin. The BOM lists a tested version for each library, so every dependency without a version gets the version that belongs to that Spring Boot release.
Listing the tasks
Let's run gradle tasks at the location where we created our build script:
Output
$ gradle tasks Starting a Gradle Daemon, 1 busy Daemon could not be reused, use --status for details
------------------------------------------------------------ Tasks runnable from root project 'boot-gradle-plugin-example' ------------------------------------------------------------
Application tasks ----------------- bootRun - Runs this project as a Spring Boot application. bootTestRun - Runs this project as a Spring Boot application using the test runtime classpath.
Build tasks ----------- assemble - Assembles the outputs of this project. bootBuildImage - Builds an OCI image of the application using the output of the bootJar task bootJar - Assembles an executable jar archive containing the main classes and their dependencies. build - Assembles and tests this project. buildDependents - Assembles and tests this project and all projects that depend on it. buildNeeded - Assembles and tests this project and all projects it depends on. classes - Assembles main classes. clean - Deletes the build directory. jar - Assembles a jar archive containing the classes of the 'main' feature. resolveMainClassName - Resolves the name of the application's main class. resolveTestMainClassName - Resolves the name of the application's test main class. testClasses - Assembles test classes.
Build Setup tasks ----------------- init - Initializes a new Gradle build. updateDaemonJvm - Generates or updates the Gradle Daemon JVM criteria. wrapper - Generates Gradle wrapper files.
Documentation tasks ------------------- javadoc - Generates Javadoc API documentation for the 'main' feature.
Help tasks ---------- artifactTransforms - Displays the Artifact Transforms that can be executed in root project 'boot-gradle-plugin-example'. buildEnvironment - Displays all buildscript dependencies declared in root project 'boot-gradle-plugin-example'. dependencies - Displays all dependencies declared in root project 'boot-gradle-plugin-example'. dependencyInsight - Displays the insight into a specific dependency in root project 'boot-gradle-plugin-example'. dependencyManagement - Displays the dependency management declared in root project 'boot-gradle-plugin-example'. help - Displays a help message. javaToolchains - Displays the detected java toolchains. kotlinDslAccessorsReport - Prints the Kotlin code for accessing the currently available project extensions. outgoingVariants - Displays the outgoing variants of root project 'boot-gradle-plugin-example'. projects - Displays the sub-projects of root project 'boot-gradle-plugin-example'. properties - Displays the properties of root project 'boot-gradle-plugin-example'. resolvableConfigurations - Displays the configurations that can be resolved in root project 'boot-gradle-plugin-example'. tasks - Displays the tasks runnable from root project 'boot-gradle-plugin-example'.
Verification tasks ------------------ check - Runs all checks. test - Runs the test suite.
Rules ----- Pattern: clean<TaskName>: Cleans the output files of a task. Pattern: build<ConfigurationName>: Assembles the artifacts of a configuration.
To see all tasks and more detail, run gradle tasks --all
To see more detail about a task, run gradle help --task <task>
BUILD SUCCESSFUL in 8s 1 actionable task: 1 executed Consider enabling configuration cache to speed up this build: https://docs.gradle.org/9.8.1/userguide/configuration_cache_enabling.html
The Spring Boot plugin tasks match the Maven plugin goals like this:
bootRun is like spring-boot:run
bootJar (or bootWar) is like spring-boot:repackage
bootBuildImage is like spring-boot:build-image
bootBuildInfo is like spring-boot:build-info. This task exists only when we add the following to the build script (it is the same in the Groovy and the Kotlin DSL):
springBoot {
buildInfo()
}
processAot is like spring-boot:process-aot, and bootTestRun is like spring-boot:test-run
There is no Gradle task like spring-boot:start and spring-boot:stop
Write our main class with a RestController
package com.logicbig.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class MainClass {
public static void main (String[] args) {
SpringApplication.run(MainClass.class, args);
}
@RestController
private static class TheController {
@RequestMapping("/")
public String handle () {
return "message from rest handler";
}
}
}
Running the application directly from classes
gradle bootRun compiles our code and runs the application from the compiled classes. It does not create a jar file.
D:\boot-gradle-plugin-example>gradle bootRun
> Task :compileJava
> Task :processResources NO-SOURCE
> Task :classes
> Task :resolveMainClassName
> Task :bootRun
...............
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v4.1.1)
2026-10-13T10:15:02.411+08:00 INFO 12376 --- [ main] com.logicbig.example.MainClass : Starting MainClass using Java 21.0.5 with PID 12376 (D:\boot-gradle-plugin-example\build\classes\java\main started by Joe in D:\boot-gradle-plugin-example)
2026-10-13T10:15:02.414+08:00 INFO 12376 --- [ main] com.logicbig.example.MainClass : No active profile set, falling back to 1 default profile: "default"
...............
2026-10-13T10:15:03.561+08:00 INFO 12376 --- [ main] com.logicbig.example.MainClass : Started MainClass in 1.186 seconds (process running for 1.532)
By default, the embedded Tomcat server listens on port 8080. Now we can access our application in the browser at http://localhost:8080:
Output
$ curl -s "http://localhost:8080" message from rest handler
We can pass options to the application with --args:
The normal jar task still works. It creates a second file with the suffix -plain in its name (boot-gradle-plugin-example-1.0-SNAPSHOT-plain.jar). This file has only our classes and it is not executable. If we do not need it, we can switch the jar task off:
tasks.jar {
enabled = false
}
tasks.named('jar') {
enabled = false
}
To build a war file, we add the war plugin to the plugins block. Then the Spring Boot plugin creates the bootWar task.
Version note: in Spring Boot 1.x, the task was called bootRepackage. It changed the normal jar after it was created, like the Maven repackage goal still does. Since Spring Boot 2.0 we use bootJar and bootWar.
Conflict between multiple main classes
Spring Boot automatically finds the 'main' class and runs it. If there is more than one main class, then we get the following error:
> Task :resolveMainClassName FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':resolveMainClassName'.
> Unable to find a single main class from the following candidates [com.logicbig.example.MainClass2, com.logicbig.example.MainClass]
To avoid that error we have to set the main class in the springBoot block. Both bootRun and bootJar use it: