【问题标题】:Publishing of a modular library to Maven using Gradle使用 Gradle 将模块化库发布到 Maven
【发布时间】:2025-11-24 15:30:01
【问题描述】:

假设我正在使用 Gradle 进行模块化库开发。在我的根项目中,我有子项目geometryalgorithmsvisualizer,我想发布每个项目的 jar 工件。

至于现在在我的根 build.gradle 我有以下部分:

apply plugin: 'maven-publish'
publishing {
    publications {
        publishDemos(MavenPublication) {
            groupId 'ru.ifmo.ctddev.igushkin.cg'
            artifactId 'geometry'
            version globalVersion
            artifact project(':geometry').tasks.getByName('jar')
        }
        publishAlgorithms(MavenPublication) {
            groupId 'ru.ifmo.ctddev.igushkin.cg'
            artifactId 'algorithms'
            version globalVersion
            artifact project(':algorithms').tasks.getByName('jar')
        }
        publishVisualizer(MavenPublication) {
            groupId 'ru.ifmo.ctddev.igushkin.cg'
            artifactId 'visualizer'
            version globalVersion
            artifact project(':visualizer').tasks.getByName('jar')
        }
    }
}

我的第一个问题:有没有更简短的方式来描述这些出版物?例如,我想声明,对于每个子项目,我都需要一个出版物,其名称中设置了 artifactId


接下来,我的子项目相互依赖,algorithmsvisualizer 都依赖于来自 geometry 的类,但此时 jar 不包含依赖项,例如,用户必须如果他们想使用algorithms,请将依赖项添加到geometryalgorithms

那么,有没有办法提供某种自动依赖,以便添加algorithms 也会添加geometry?如果是,我该怎么做?如果不是,提供模块化库的惯用方式是什么?我应该组装带有依赖项的 jars 吗?

UPD:我应该只使用from project(':...').components.java 而不是artifact ...,因为它会同时获取工件和依赖项,对吗?如果我使用artifact ...,如何单独选择依赖项?

【问题讨论】:

    标签: gradle dependencies publishing modularity maven-publish


    【解决方案1】:

    您可以通过将相同的发布配置注入每个子项目来减少冗长的发布声明。例如对于具有以下结构的多构建项目:

    ROOT
    │   build.gradle
    │   settings.gradle
    ├───subA
    │       build.gradle
    │
    ├───subB
    │       build.gradle
    │
    └───subC
            build.gradle
    

    在你的根build.gradle,你可以这样做:

    apply plugin:'maven-publish'
    
    subprojects{
        publishing {
            publications {
                "$project.name"(MavenPublication) {
                    groupId project.group
                    artifactId project.name
                    version project.version
                    from components.java
                }
            }
        }
    }
    

    每个子项目都定义了自己的 groupid 和版本,如下所示:

    group = 'org.test.sample.A'
    version = '1.0'
    

    artifactId 取自子项目名称。运行 gradle publish 会生成此结构的 repo:

    org
    └───test
        └───sample
            ├───A
            │   └───subA
            │       └───1.0
            │               subA-1.0.jar
            │               subA-1.0.pom
            ├───B
            │   └───subB
            │       └───1.0
            │               subB-1.0.jar
            │               subB-1.0.pom
            └───C
                └───subC
                    └───1.0
                            subC-1.0.jar
                            subC-1.0.pom
    

    依赖关系

    此配置还会自动处理依赖项。例如,如果在子项目subA 你有:

    dependencies{
        compile project(':subB')
    }
    

    由于我使用的是from components.java 而不是artifact,因此插件知道查找依赖项并为subA 生成一个pom,其中包括:

      <dependencies>
        <dependency>
          <groupId>org.gradle.sample.B</groupId>
          <artifactId>subB</artifactId>
          <version>1.0</version>
          <scope>runtime</scope>
        </dependency>
      </dependencies>
    

    【讨论】:

    • 绝对精彩的答案。谢谢你:)
    • 这可行,但会产生像:generatePomFileForFooPublication 这样的任务,而不是:foo:generatePomFileForMavenPublication,我想要这样我可以用一个命令完成所有发布。但是,如果我将"$project.name" 替换为maven,它会抱怨Maven publication 'maven' cannot include multiple components。有什么办法可以使这项工作?谢谢!
    • @max 答案说(写了答案,但几年前,我不记得具体细节)运行gradle publish 应该在1 次,这对你不起作用吗?
    最近更新 更多