使用 gradle 为 spring 启动生成多个 jar

Generating multiple jars for spring boot with gradle

我的项目是 spring 使用 gradle 启动。我的目标是让 spring 引导生成 2 个不同的引导 jar。第一个 jar 是今天创建的典型 jar,将用于生产系统。第二个 jar 将被其他系统用于集成测试。第二个 jar 会有一组不同的配置和依赖项。还有其他人这样做吗?我没有看到 bootJar 任务的任何简单配置,也没有成功尝试基于 bootJar.

创建自己的任务

更新:以下是基于 Francisco Mateo 的回答的解决方案。

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

您需要基本上复制 Spring 引导插件创建 bootJar 的方式,如 source 中所示。大部分逻辑都包含在任务本身中,因此您所要做的就是创建另一个 BootJar 任务类型并稍作修改,主要是添加不属于主 JAR 的其他依赖项。

完整示例(未经测试):

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")
    }
}

上面的集成测试配置实际上是取自Gradle文档的示例:https://docs.gradle.org/current/userguide/java_testing.html#sec:configuring_java_integration_tests

tasks { } 中,您可以看到创建集成测试特定 Boot JAR 的位置与 Spring Boot 插件创建 bootJar 的方式相同。但是,这里的主要区别在于添加了集成测试运行时类路径。