如何在多模块 Gradle 项目中构建分发包?

Posted

技术标签:

【中文标题】如何在多模块 Gradle 项目中构建分发包?【英文标题】:How to build distribution package in multi-module Gradle project? 【发布时间】:2019-10-06 12:45:47 【问题描述】:

我看过这个帖子Gradle multi project distribution,但还是有些疑惑。 我想创建以下项目布局

根 |--lib-java-模块 |--spring-boot-module |--3PP_A_module # 不是java | |-- 自定义脚本,配置 |--3PP_B_module # 不是java | |-- 自定义脚本,配置 |--dist-模块

您可能已经猜到了,我希望 dist 模块使用 libjava.jar、sprintbootapp.jar、3pp-a.tar、3pp-b.tar 构建 myapp-dist.tar.gz。

myapp-dist.tar.gz libjava.jar sprintbootapp.jar 3pp-a.tar 3pp-b.tar。

3pp-a-module 和 3pp-b-module 只包含一些配置文件和启动脚本。没有java或任何编译代码。如何将它们单独打包成 tar 文件(无压缩)?

如何定义 dist-module 中对其他模块的依赖关系?从 dist-module 触发构建时是否可以构建其他模块?

更新:

我根据@marco-r 的回答设置了我的测试项目,除了打包war 文件外,它可以正常工作。从 github https://github.com/KiranMohan/study-spring-boot 签出测试项目。

这是感兴趣的项目设置。

include ':sb-2.1-multi-package', ':sb-2.1-multi-package:hello-rest-lib', 
        ':sb-2.1-multi-package:hello-rest-standalone-jar',
        ':sb-2.1-multi-package:hello-rest-war'
include 'sb-2.1-3pp-resources'
include 'sb-2.1-build'

但是将 hello-rest-war 添加到 sb-2.1-build.tar.gz 失败。 而不是 war 文件,它是被打包的依赖项。

dependencies 
    archivesDeps    project(path: ':sb-2.1-3pp-resources', configuration: 'archives')
    javaDeps project(":sb-2.1-multi-package:hello-rest-war")


...    
task copyJavaDeps(type: Copy) 
    inputs.files(configurations.javaDeps)
    from configurations.javaDeps
    into "$ARCHIVE_DIRECTORY/lib"


...
// create distribution bundle
distributions 
    main 
        contents 
            from ARCHIVE_DIRECTORY
            into "/springapp/multimodule"
        
    

包的内容

springapp/multimodule/lib/classmate-1.4.0.jar
springapp/multimodule/lib/hello-rest-lib-0.0.1-SNAPSHOT.jar
springapp/multimodule/lib/hibernate-validator-6.0.16.Final.jar
...
springapp/multimodule/lib/tomcat-embed-websocket-9.0.17.jar
springapp/multimodule/lib/validation-api-2.0.1.Final.jar    
springapp/multimodule/sb-2.1-3pp-resources/config/3pp.json

如何打包war文件(hello-rest-war模块)并且没有所有传递依赖?

【问题讨论】:

【参考方案1】:

这是多个问题的场景,所以我将分部分解决。

    由于所有 3PP_X_module 都具有相同的构建要求,因此在每个子模块中创建一个 build.gradle,以引用具有所需通用功能的实际构建 gradle:
apply from: '../tarArtifact.gradle'
    在父文件夹中创建先前引用的tarArtifact.gradle,以具有对引用子项目的子文件夹(任意选择为contents)的内容进行 TAR 的功能:
apply plugin: 'base'

task tarContents(type: Tar) 
    from 'contents'
    archiveName = "$project.name.tar"
    destinationDir file('build/tar')


artifacts 
    archives file: tarContents.archivePath, type: 'tar', builtBy: tarContents

由于archives 配置连接到tarContents (builtBy: tarContents) 的输出,因此archives 配置可用于检索所需的TAR 作为构建此项目的输出自然。

    dist-module 中创建以下build.gradle 文件:
apply plugin: 'distribution'

plugins.withType(DistributionPlugin) 
    distTar 
        compression = Compression.GZIP
        extension = 'tar.gz'
    


configurations 
    wholeProjectDist


dependencies 
    wholeProjectDist project(path: ':3pp-a-module', configuration: 'archives')
    wholeProjectDist project(path: ':3pp-b-module', configuration: 'archives')
    wholeProjectDist project(':lib-java-module')
    wholeProjectDist project(':spring-boot-module')


distributions 
    main 
        contents 
            from configurations.wholeProjectDist
        
    

这个 gradle 文件包括以下内容:

应用Distribution plugin,因此我们可以从所有其他子项目生成的工件生成最终的tar.gz 文件。 配置distTar 任务(DistributionPlugin 插件)使用GZIP 压缩任何生成的TAR。 创建配置wholeProjectDist以捕获dist-module本身的依赖关系;我们将与分发插件的任务一起使用。 将dist-module 的依赖声明为兄弟姐妹子项目输出的工件;使用新创建的wholeProjectDist。 将发行版的插件main 配置为具有contents 来自configurations.wholeProjectDist 的所有文件
    dist-module 下创建一个settings.gradle 文件,以允许它使用includeFlat 访问其兄弟模块:
includeFlat '3pp-a-module', '3pp-b-module', 'lib-java-module', 'spring-boot-module'
    在父文件夹中包含一个settings.gradle 文件以包含所有子子模块(作为根项目):
includeFlat '3pp-a-module', '3pp-b-module', 'lib-java-module', 'spring-boot-module'
    通过调用 gradle 命令(从根文件夹)构建所需的 tar.gz 文件:
gradle :dist-module:distTar

希望这会有所帮助。

【讨论】:

第二步,为什么不用分发插件呢? 你可以;但我发现构建起来比配置起来更简单。 将war文件添加到分发包时出错。请检查我的问题的更新。

以上是关于如何在多模块 Gradle 项目中构建分发包?的主要内容,如果未能解决你的问题,请参考以下文章

如何在多模块spring boot应用程序gradle中只访问不同模块的一个类?

如何在多平台多项目 Kotlin 构建中向另一个项目的测试添加依赖项

Gradle多项目构建与jar包发布

Gradle / javacard插件是否支持在多项目gradle构建中构建两个applet依赖项?

gradle杂述

在多模块 Maven 项目中构建所有模块后,如何运行集成测试?