如何在一个gradle项目中生成所有项目?

vdzxcuhz  于 2021-07-03  发布在  Java
关注(0)|答案(2)|浏览(590)

我有一个gradle单片项目,有太多的依赖关系。
我想把它分解成许多子项目并发布所有子项目(build+sources+javadoc)+一个额外的项目是所有子项目的合并。
这个额外的项目应该像一个虚拟的工件,把我所有的项目都放在一个jar中,就像今天一样,因为我不想让我的用户有太大的改变。
jar不能包含依赖项(它不是uber jar),但是生成的pom.xml必须包含所有子项目的依赖项(maven工件生成的pom.xml必须包含所有依赖项)。
虚拟工件也将包括javadoc和源代码的合并,以便遵守maven中心约定。
当前状态:
项目主,生成
pom.xml文件
main.jar文件
main-sources.jar文件
main-javadoc.jar
预期状态:
子项目a,生成
a-pom.xml文件
a、 jar
a源.jar
a-javadoc.jar文件
子项目b,生成
b-pom.xml文件
b、 jar
b源.jar
b-javadoc.jar文件
virtal项目主,生成
pom.xml=a-pom.xml+b-pom.xml
main.jar=a.jar+b.jar
main sources.jar=a-sources.jar+b-sources.jar
main javadoc.jar=a-javadoc.jar+b-javadoc.jar
我怎么办?

gwo2fgha

gwo2fgha1#

这不可能用 maven-publish 直接,但可以添加个人 java-library 模块,并用源代码和文档对每个模块进行打包。对于grad尔来说,这将是一个简单的问题 jar 任务,但当工件是公开可用的…这种可传递的依赖关系最好由元包提供;除了maven(local/central)依赖项之外什么都没有,而不是嵌入jar。在本例中,这只是另一个模块(显然只有在发布了其他模块之后才能构建)。
关于这个概念,它需要任何“合并”的javadocs。。。https://central.sonatype.org/pages/requirements.html#supply-javadoc和源代码
当它们被引用时(maven central) *.pom ,grad尔就能找到他们。
只使用存储库 mavenLocal() 而不是 mavenCentral() 用于测试目的。

dfty9e19

dfty9e192#

我们已经有一段时间处于完全相同的情况了。我们希望为我们的客户发布一个可依赖的工件,尽管在内部产品是通过几个单独的组件项目开发的。我最终完成了(妥协),以下是我学到的:
合并jar并不像看上去那么简单,因为jar中可能有资源文件这样的东西并不总是命名空间化的。可能两个jar有一个同名的资源文件,在这种情况下,您必须合并这些文件的内容。
如果不访问原始源文件,javadoc很难合并,因为它有摘要页(索引页)。
所以我的建议是:
三思而后行,也许你真正想要的不是一个jar,而是对你的客户的一个依赖?这些是不同的。你可以很容易地拥有一个只有pom的神器。依赖于这个pom-only工件将简单地转换为依赖于组件子项目的各个工件。实际上,对你的客户来说,一切都没有改变。SpringBoot采用这种方法。为此,您可以创建一个空的java库项目,使所有组件项目都是它的 api 附属国。在这个项目中你甚至不需要任何源代码。
如果您真的想合并到一个jar中,可以尝试通过定制构建一个胖jar。定制不是为了拉入第三方依赖项。
我们使用gradleshadow插件来合并jar。它最初的目的是构建一个胖jar,它将包含所有可传递的依赖项。但它也有一个特殊的 shadow “配置,如果希望将依赖项导出到pom而不是捆绑,则可以向其中添加依赖项。所以你需要做的是:
定义一个不可传递的配置(比如bundler),将子项目作为依赖项添加到该配置中。这将是gradleshadow插件的目标配置。
定义一个可传递的配置(bundlertransitive),它从非可传递的配置扩展而来。这将被手动解决,以便找到第三方的依赖关系
在build.gradle中,注册 afterEvaluate 闭包,在这里您可以找到解析的可传递配置的二级依赖项,将它们添加到 shadow 配置。第二级的原因是第一级依赖项将是您的子项目工件。
所有这些之后,shadowjar任务生成的工件就是要上传到maven的工件。您需要配置shadowjar任务来删除分类器(默认情况下是shadow)
下面是一个完整的示例(build.gradle),它将vertx web及其所有依赖项绑定到io.vertx组中:

plugins {
    id 'java'
    id 'maven-publish'
    id 'com.github.johnrengelman.shadow' version '5.2.0'
}

group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

configurations {
    bundler {
        transitive = false
    }

    bundlerTansitive {
        extendsFrom bundler
        transitive = true
    }
}

dependencies {
    bundler "io.vertx:vertx-web:4.0.0"
    bundler "io.vertx:vertx-web-common:4.0.0"
    bundler "io.vertx:vertx-core:4.0.0"
    bundler "io.vertx:vertx-auth-common:4.0.0"
    bundler "io.vertx:vertx-bridge-common:4.0.0"
}

shadowJar {
    configurations = [project.configurations.bundler]
    classifier ''
}

publishing {
    publications {
        shadow(MavenPublication) { publication ->
            project.shadow.component(publication)
        }
    }
}

project.afterEvaluate {
    // this is needed because your sub-projects might have inter-dependencies
    def isBundled = { ResolvedDependency dep ->
        return configurations.bundler.dependencies.any {
            dep.moduleGroup == it.group && dep.moduleName == it.name
        }
    }

    logger.lifecycle '\nBundled artifacts and their 1st level dependencies:'

    // level one dependencies
    configurations.bundlerTansitive.resolvedConfiguration.firstLevelModuleDependencies.forEach {
        logger.lifecycle "+--- ${it.getName()}"

        // level two dependencies
        it.children.findAll({ ResolvedDependency dep -> !isBundled(dep) })
                .forEach { ResolvedDependency dep ->
                    logger.lifecycle "|    +--- ${dep.name}"
                    project.dependencies.add('shadow', [group: dep.moduleGroup, name: dep.moduleName, version: dep.moduleVersion])
                }
    }

    logger.lifecycle '\nExported Dependencies:'

    configurations.shadow.getResolvedConfiguration().getFirstLevelModuleDependencies().forEach {
        project.logger.lifecycle "+--- ${it.getName()}"
    }
}

对于javadoc,如果您不关心索引(如我所说的折衷),那么它只是一个带有拷贝规范的jar任务:

configurations {
   javadoc {
        transitive = false
    }
}

dependencies {
    javadoc 'com.my:component-a:1.1.0:javadoc'
    javadoc 'com.my:component-b:1.1.0:javadoc'
    javadoc 'com.my:component-c:1.1.0:javadoc'
    javadoc 'com.my:component-d:1.1.0:javadoc'
}

task javadocFatJar(type: Jar) {
    archiveClassifier.set('javadoc')
    from { 
        configurations.javadoc.collect { it.isDirectory() ? it : zipTree(it) } 
    }
    with jar
}

相关问题