9

Spring boot 2.3.0 has the layered fat jars which are optimized for container image builds. Now, the Spring documentation discusses only Maven build tool, and not Gradle.

Please, what do we need to do to the Gradle plugin to allow it to build a "layered jar" for spring boot?

For example: if extracting a jar with the command java -Djarmode=layertools -jar app.jar extract which has been made with Gradle Spring boot plugin id("org.springframework.boot") version "2.3.0.RELEASE" it fails with message: Unsupported jarmode 'layertools'. Basically if the jar has been built with ./gradlew bootJar it seems layered jar is not active by default.

Extracting a layered jar should result in the following directories, and these are then copied into another container image for execution, and only if lower layers have changed does the caching system have to re-read them. Layered jar extracted with -Djarmode=layertools flag:

./dependencies/
./snapshot-dependencies/
./resources/
./application/

The blog at spring Spring Blog 2.3.0.ML discusses Maven build tool and the configuration:

<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
    <layout>LAYERED_JAR</layout>
</configuration>

How do we enable the same configuration for Gradle plugin?

kaicarno
  • 416
  • 5
  • 12
  • Check the contents of the Gradle layered JAR with `java -Djarmode=layertools -jar build/libs/*.jar list`... because with Gradle I get a `spring-boot-loader` folder... which seems to not be the case with maven... equally the `resources` folder does not exist in the Gradle plugin's layered Jar. – kaicarno Jun 09 '20 at 21:17

2 Answers2

10

The documentation is available for how to activate the layered fat jar for spring boot applications with the spring-boot-gradle-plugin.

See the details at Packaging Layered Jars with Gradle.

In the build.gradle file:

// Groovy solution
bootJar {
    layered()
}


// Kotlin solution
tasks.getByName<BootJar>("bootJar") {
    layered()
}

Hope this helps.

kaicarno
  • 416
  • 5
  • 12
  • 1
    A slightly more concise version of the Kotlin version is `tasks.bootJar{layered()}` – PaulNUK Aug 23 '20 at 11:09
  • This is what you need in case you're writing a groovy plugin: `project.tasks.withType(BootJar).first().layered.includeLayerTools = true` – Alex Dec 04 '20 at 19:43
4

You can also find more information in here:

https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/gradle-plugin/reference/html/#packaging-layered-jars

bootJar {
  layered {
    enabled = true

    application {
      intoLayer("spring-boot-loader") {
        include "org/springframework/boot/loader/**"
      }
      intoLayer("application")
    }
    
    dependencies {
      intoLayer("snapshot-dependencies") {
        include "*:*:*SNAPSHOT"
      }
      intoLayer("dependencies")
    }

    layerOrder = ["dependencies", "spring-boot-loader", "snapshot-dependencies", "application"]
  }
}

You will find corresponding layer names in layers.idx file inside you JAR.

mate00
  • 2,727
  • 5
  • 26
  • 34