Home > Blockchain >  Generating multiple jars for spring boot with gradle
Generating multiple jars for spring boot with gradle

Time:03-12

My project is spring boot with gradle. My goal is to have spring boot generate 2 different boot jars. The first jar is the typical jar created today which would be used in production systems. The second jar would be used by other systems for integration testing. The second jar would have a different set of configuration and dependencies. Has anyone else done this? I did not see any simple configuration for the bootJar task nor was i successful trying to create my own task based on bootJar.

UPDATE: Below is the solution which worked based upon Francisco Mateo's answer.

configurations {
    integrationImplementation.extendsFrom implementation
    integrationRuntimeOnly.extendsFrom runtimeOnly
    //...
}


dependencies {
    // ...

    integrationRuntimeOnly 'com.h2database:h2'

    // ...
}

sourceSets {
    integration {
        compileClasspath  = sourceSets.main.output
        runtimeClasspath  = sourceSets.main.output
    }
}
tasks.register("integrationBootJar", BootJar) {
    description = "Assembles an executable JAR archive to be used for integration tests of other projects containing the main classes, their dependencies, and any other integrationImplementation or integrationRuntimeOnly dependencies."
    group = 'build' 
    classpath = sourceSets.main.runtimeClasspath.plus(sourceSets["integration"].runtimeClasspath)
    mainClass.set("${jarMainClass}") // TODO can pull from bootJarMainClassName or bootRunMainClassName like bootJar?
    archiveClassifier.set("integration")
    shouldRunAfter bootJar
}
assemble.dependsOn integrationBootJar

CodePudding user response:

You would need to essentially duplicate the way the Spring Boot plugin creates bootJar as shown here in the source. Most of the logic is contained within the task itself, so all you have to do is create another BootJar task type with some slight modifications, mainly adding additional dependencies that are not part of the main JAR.

Complete example (untested):

import org.springframework.boot.gradle.plugin.SpringBootPlugin
import org.springframework.boot.gradle.tasks.bundling.BootJar

plugins {
    id("org.springframework.boot") version "2.6.4"
    id("java")
}

group = "io.mateo"

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(17))
    }
}

repositories {
    mavenCentral()
}

sourceSets {
    register("integrationTest") {
        compileClasspath  = sourceSets.main.get().output
        runtimeClasspath  = sourceSets.main.get().output
    }
}

val integrationTestImplementation by configurations.getting {
    extendsFrom(configurations.implementation.get())
}

dependencies {
    implementation(platform(SpringBootPlugin.BOM_COORDINATES))
    implementation(platform("org.springframework.cloud:spring-cloud-dependencies:2021.0.1"))
    implementation("org.springframework.boot:spring-boot-starter-web")
    integrationTestImplementation("org.apache.commons:commons-lang3:3.12.0")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

tasks {
    test {
        useJUnitPlatform()
    }
    register("integrationTestBootJar", BootJar::class) {
        description = "Assembles an integration test executable JAR archive containing the main classes and their dependencies."
        group = BasePlugin.BUILD_GROUP
        classpath = sourceSets.main.get().runtimeClasspath.plus(sourceSets["integrationTest"].runtimeClasspath)
        mainClass.set("io.mateo.springdemo.SpringdemoApplication")
        archiveClassifier.set("integration-test")
    }
}

The above integration test configuration is actually an example taken from the Gradle documentation: https://docs.gradle.org/current/userguide/java_testing.html#sec:configuring_java_integration_tests

In the tasks { } you can see where the integration test specific Boot JAR is created the same way the Spring Boot plugin creates bootJar. However, the key difference here is addition of the integration test runtime classpath.

  • Related