skip to content

How do you enable/verify layered-jar packaging in the Spring Boot build plugin, and how can you inspect a jar's layers?

level: middleimportance: should knowfreq 35%

answer

  1. default since 2.4 (opt-in in 2.3)
  2. bootJar / repackage 'layered' block
  3. layertools list = quick check
  4. unzip BOOT-INF/layers.idx
  5. index missing == not layered

basics

~20 s

Layering is on by default since Spring Boot 2.4 via the Gradle/Maven Boot plugin. You can toggle it in the plugin's layered config. To inspect, run java -Djarmode=layertools -jar app.jar list, or unzip and open BOOT-INF/layers.idx.

solid answer

~40 s

Since **Spring Boot 2.4** the build plugins produce layered jars **by default** (in 2.3 you opted in with `layered { enabled = true }`). The `spring-boot-gradle-plugin`'s `bootJar` task and the `spring-boot-maven-plugin`'s `repackage` goal both expose a `layered` configuration block where you can disable it, redefine layers, or set `layerOrder`. To confirm a built jar is layered, run **`java -Djarmode=layertools -jar app.jar list`**, which prints the layer names from `BOOT-INF/layers.idx`; or unzip the jar and read `BOOT-INF/layers.idx` directly — an ordered index mapping layer names to paths. Its presence proves layering is enabled. You typically don't need to change anything: the default four-layer scheme works for most apps, and customization is reserved for splitting out internal libraries or matching an unusual change-frequency profile.

code

java · 14 lines
java
// Shell inspection commands (java-fenced for readability):
//
// 1) Print layer names from the index:
//    java -Djarmode=layertools -jar app.jar list
//    -> dependencies
//       spring-boot-loader
//       snapshot-dependencies
//       application
//
// 2) Read the raw index without extracting:
//    unzip -p app.jar BOOT-INF/layers.idx
//
// 3) Disable layering (Gradle, Boot 2.4+ — rarely needed):
//    tasks.bootJar { layered { enabled = false } }

go deeper

for a junior

Know it's on by default and that layertools list shows the layers.

for a middle

Name the plugin tasks/goals, the version history (2.3 opt-in, 2.4 default), and layers.idx as the proof.

for a senior

Discuss customizing intoLayer/layerOrder and the catch-all requirement that every path map to a layer.

for a principal

Decide org policy on default vs custom layering and how CI verifies image layer structure.

### Enabling (it's default) Layered packaging is produced by the Spring Boot build plugins: - **Gradle:** the `org.springframework.boot` plugin's **`bootJar`** task. - **Maven:** the **`spring-boot-maven-plugin`**'s **`repackage`** goal (bound to `package`). Since **Spring Boot 2.4**, layering is **on by default** — no config needed. In **2.3** it was opt-in: ```groovy // Gradle, Boot 2.3 (historical) bootJar { layered { enabled = true } } ``` ```xml <!-- Maven, Boot 2.3 (historical) --> <configuration><layers><enabled>true</enabled></layers></configuration> ``` From 2.4+ you only touch this to **disable** or **customize** it. ### Customizing The `layered` block lets you redefine layer content (`intoLayer` with include/exclude filters on dependencies or application resources) and the copy order (`layerOrder` in Gradle / `<layerOrder>` in Maven). See the default: `dependencies`, `spring-boot-loader`, `snapshot-dependencies`, `application`. ### Verifying / inspecting a built jar Three ways: 1. **`java -Djarmode=layertools -jar app.jar list`** — prints the layer names in order straight from `layers.idx`. Fast sanity check. 2. **Unzip + read `BOOT-INF/layers.idx`** — e.g. `unzip -p app.jar BOOT-INF/layers.idx`. It's an ordered YAML-like list mapping each layer to its paths. If the file is missing, the jar is **not** layered. 3. **`extract`** (`java -Djarmode=layertools -jar app.jar extract`) — actually unpacks the layers into directories; overkill just to inspect but definitive. ### Gotchas - **`layers.idx` presence == layered.** If a build set `enabled = false` or you're on pre-2.3, the index is absent and `list` errors / shows nothing. - Boot **3.3+** prefers `-Djarmode=tools` for extraction, but `layertools list` still works for inspection. - Customizing content requires **every** path to map to a layer; leftover unmatched files fail the build — hence the default catch-all `intoLayer("application")` / `intoLayer("dependencies")` rules. - Changing layers affects only packaging/caching, never runtime behavior. - Disabling layering is rarely justified; the main reason would be a build pipeline that predates layering support or a tool that can't handle the index.

  • How can you tell from an unpacked jar whether it is layered?
    Check for the file BOOT-INF/layers.idx. If it exists, the jar is layered and the file lists each layer and its paths in order; if it's absent, layering was disabled or the Boot version predates the feature.
  • Which Spring Boot version made layering the default?
    Spring Boot 2.4. It was introduced as opt-in in 2.3, then became the default in 2.4 so you no longer need any configuration to get layered jars.

saying these in an interview costs you the question

  • Thinking you must manually enable layering on modern Spring Boot
  • Claiming there's no way to inspect the layers of a built jar
  • Confusing the `layered` build config with a runtime setting

context