skip to content

Spring Boot Plugin Overview

The Spring Boot plugin's bootJar and bootRun tasks and its dependency-management integration for BOM-aligned versions. Asked in nearly every Spring interview that touches the build.

on this pageshow

questions

5

What does the Spring Boot Gradle plugin do, and what is the difference between bootJar and the standard jar task?

level: juniorimportance: must knowfreq 78%

answer

  1. bootJar = fat/executable jar
  2. BOOT-INF/lib + BOOT-INF/classes
  3. JarLauncher Main-Class, Start-Class
  4. plain jar disabled by default
  5. layered jar / layers.idx

basics

~10 s

Applying org.springframework.boot adds a bootJar task that builds an executable 'fat jar' bundling your code plus all dependencies and a launcher. The plain jar task only packages your own classes.

solid answer

~40 s

The `org.springframework.boot` plugin registers the `bootJar` task, which produces a self-contained executable jar (a 'fat' or 'uber' jar) you can run with `java -jar`. It nests dependency jars under `BOOT-INF/lib`, your classes under `BOOT-INF/classes`, and adds a `Main-Class` of `JarLauncher` plus a `Start-Class` manifest entry pointing at your `@SpringBootApplication`. The plugin also reacts to the `java` plugin and **disables** the standard `jar` task by default (because a thin jar isn't directly runnable), and makes `assemble` depend on `bootJar`. There's a parallel `bootWar` for war packaging and `bootRun` for running the app in-place. So `jar` = plain library jar of just your classes; `bootJar` = layered, launchable application archive.

code

bash · 6 lines
bash
# Build the executable jar
./gradlew bootJar
# Run it standalone — no Gradle, no classpath flags needed
java -jar build/libs/myapp-0.0.1-SNAPSHOT.jar
# Inspect the layout
unzip -l build/libs/myapp-0.0.1-SNAPSHOT.jar | head

go deeper

for a junior

Know that bootJar makes a runnable fat jar and that plain jar only has your classes.

for a middle

Explain the BOOT-INF layout, the launcher main-class/Start-Class, and that the plain jar is disabled by default.

for a senior

Discuss layered jars for image caching, re-enabling jar for library modules, and the assemble/bootJar wiring.

for a principal

Frame packaging strategy across a monorepo: fat jar vs OCI image (bootBuildImage), publishing thin library jars, and standardizing layering for build-cache and registry efficiency.

## What the plugin is `org.springframework.boot` is the official Gradle plugin for Spring Boot applications. Applying it does not by itself add Spring dependencies — it wires up **packaging and running** tasks and reacts to other plugins. ## bootJar vs jar The core deliverable is the **executable jar** built by the `bootJar` task. A normal `jar` task produces an archive containing only your compiled classes and resources — it is not runnable, because the JVM has no way to load your transitive dependencies from inside one jar. Spring Boot solves this with a custom layout and a launcher: - `BOOT-INF/classes/` — your application classes and resources - `BOOT-INF/lib/` — every runtime dependency jar, nested - `org/springframework/boot/loader/...` — the loader classes - `META-INF/MANIFEST.MF` with `Main-Class: org.springframework.boot.loader.launch.JarLauncher` and `Start-Class: com.example.MyApplication` When you run `java -jar app.jar`, the JVM invokes `JarLauncher`, which sets up a classloader able to read nested jars, then calls your `Start-Class`'s `main`. ## Interaction with the java plugin When both `java` and Spring Boot are applied, the plugin: - registers `bootJar` and makes `assemble` depend on it, - **disables the plain `jar` task** by default (set `tasks.named("jar") { enabled = true }` if you also need a thin jar, e.g. to publish a library), - registers `bootRun` to launch the app using the `main` source set's runtime classpath. ## Layered jars Modern `bootJar` produces a **layered** jar (a `layers.idx` index) so Docker builds can split rarely-changing dependency layers from frequently-changing application layers, improving image-build caching. Layering is on by default. ```kotlin plugins { java id("org.springframework.boot") version "3.3.0" } tasks.named<org.springframework.boot.gradle.tasks.bundling.BootJar>("bootJar") { archiveClassifier.set("boot") } ``` ## Key takeaway `jar` = your classes only, not runnable. `bootJar` = self-contained, launchable, layered application archive with a launcher main-class.

  • Why is the plain jar task disabled when Spring Boot is applied, and when would you re-enable it?
    Because a thin jar isn't independently runnable, so it's a misleading default artifact. Re-enable it if the module is also a reusable library that others depend on, where you want a normal jar published alongside (or instead of) the fat jar.
  • What is a layered jar and why does it matter?
    bootJar writes a layers.idx splitting contents into layers (dependencies, spring-boot-loader, snapshot deps, application). Container tooling can map each layer to a separate Docker layer so rebuilds only re-push the small, frequently-changing application layer.

A plain jar is a recipe card; a bootJar is the whole meal-kit box with every ingredient and the instructions to cook it included.

saying these in an interview costs you the question

  • Saying jar and bootJar produce the same thing
  • Claiming the plugin adds Spring dependencies automatically (it doesn't — that's the starters)
  • Thinking you must list dependencies on the java -jar classpath

context

open as a page

How does io.spring.dependency-management relate to the Spring Boot plugin, and how does BOM-aligned version management work in a Gradle build?

level: middleimportance: must knowfreq 70%

basics

~10 s

The Spring Boot plugin imports the Boot BOM so you can declare dependencies without versions, and Gradle resolves consistent, tested versions for you. Versionless starters 'just work' because the BOM pins them.

open as a page

Given a fresh Gradle build, show how you'd apply the Spring Boot plugin and explain why applying it alone doesn't pull in Spring dependencies.

level: juniorimportance: should knowfreq 55%

basics

~10 s

Add id("org.springframework.boot") in the plugins block. That only wires up tasks like bootJar/bootRun and the BOM; you still declare starters such as spring-boot-starter-web yourself to get actual Spring code.

open as a page

What is the bootRun task, and how do you pass arguments, JVM options, system properties, or an active profile to it?

level: middleimportance: should knowfreq 60%

basics

~10 s

bootRun launches your Spring Boot app from the build using the main source set's runtime classpath, without building a jar first. You configure it to pass program args, JVM flags, and system properties.

open as a page

How does the Spring Boot plugin's task design (lazy registration, inputs/outputs, config-cache compatibility) affect build performance and correctness, and what pitfalls have you hit configuring bootJar/bootRun?

level: seniorimportance: should knowfreq 35%

basics

~10 s

The plugin registers bootJar/bootRun lazily and declares proper task inputs/outputs so they're incremental and cacheable. Misconfiguring them — e.g. eager resolution or non-cacheable inputs — breaks up-to-date checks and the configuration cache.

open as a page