spring-bootspring-boot-gradle-plugin

When building layered jars in Spring Boot, how do you include a multi-module projects jars in a layer?


According to the Spring Boot gradle plugin reference, I should be able to package a particular pattern of jars into a specific layer (for making better docker files).

I'm confused about the pattern matching used in the documentation. Here's an example:

tasks.getByName<BootJar>("bootJar") {
    layered {
        isIncludeLayerTools = true
        application {
            intoLayer("spring-boot-loader") {
                include("org/springframework/boot/loader/**")
            }
            intoLayer("application")
        }
        dependencies {

            intoLayer("module-dependencies") {
                include("com*:*:*")
            }

            intoLayer("dependencies")
        }
        layerOrder = listOf("dependencies", "spring-boot-loader", "module-dependencies", "application")
    }
}

What I don't understand is what this pattern matching is matching on:

intoLayer("module-dependencies") { include("com*::") }

Is it the group, artifact and version of a jar ? Is it the name of the jar ?

If I have a multi-module project that has modules aa,ab and ac, equating to aa.jar, ab.jar and ac.jar and an external dependency org.something:anartifact:25 equating to anartifact-25.jar what pattern do I need to add to include aa,ab and ac in one layer and every other dependency in another layer ?


Solution

  • For module dependencies the pattern is <group>:<artifactid>:<version>. You can using trailing wildcard to match a subset of items or omit the item entirely to match everything. For example, com.fasterxml.jackson:: will match all artifact and all versions in the com.fasterxml.jackson group.

    In the case of a multi-module project, by default the artifactid is the name of the project and the group is the value of the group value set in your build.gradle.

    It's usually common to define the group in the root project's build.gradle file, for example:

    allprojects {
      group "com.example"
      version = '0.0.1-SNAPSHOT'
      repositories {
        mavenCentral()
      }
    }
    

    You can then define the layer patterns as follows in your application module:

    bootJar {
        layered {
            application {
                intoLayer("spring-boot-loader") {
                    include("org/springframework/boot/loader/**")
                }
                intoLayer("application")
            }
            dependencies {
                intoLayer("module-dependencies") {
                    include("com.example:*:*")
                }
                intoLayer("dependencies")
            }
            layerOrder = [ "dependencies", "spring-boot-loader", "module-dependencies", "application" ]
        }
    }
    

    I've uploaded a sample to https://github.com/philwebb/mutli-module-layered-gradle-example that shows this in a complete project.