使用 gradle 为 Spring Boot 生成多个 jar

发布于 2025-01-12 06:20:40 字数 1306 浏览 1 评论 0原文

我的项目是带有gradle的spring boot。我的目标是让 Spring Boot 生成 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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无戏配角 2025-01-19 06:20:40

您需要基本上复制 Spring Boot 插件创建 bootJar 的方式,如 。大多数逻辑都包含在任务本身中,因此您所要做的就是创建另一个 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

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

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.

新一帅帅 2025-01-19 06:20:40

我成功地使用了更简短的形式,我的任务是仅重新定义 mainClass,硬性要求是提供 targetJavaVersion 和类路径:

tasks.named("bootJar", BootJar.class).configure {
    mainClass = "com.evil.app.ServerApp"
}

tasks.register("bootJarH2", BootJar.class) {
    group = bootJar.group
    description = bootJar.description
    targetJavaVersion = bootJar.targetJavaVersion
    classpath = bootJar.classpath
    mainClass = "com.evil.app.H2App"
}

I succeeded with a shorter form, my task was to redefine only mainClass, hard requirements were to supply targetJavaVersion & classpath:

tasks.named("bootJar", BootJar.class).configure {
    mainClass = "com.evil.app.ServerApp"
}

tasks.register("bootJarH2", BootJar.class) {
    group = bootJar.group
    description = bootJar.description
    targetJavaVersion = bootJar.targetJavaVersion
    classpath = bootJar.classpath
    mainClass = "com.evil.app.H2App"
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文