当前位置: 首页 > 知识库问答 >
问题:

第5级Kotlin DSL:多模块项目中的常见任务和Maven工件

韦昊焜
2023-03-14

我真的很想欣赏Gradle5,特别是结合了新的Kotlin DSL,但是我很难获得(在我看来)一个非常非常简单和普通的构建与Gradle一起运行。

在Maven default目录布局中发布一个Java库,其中包含几个相互依赖的子模块,作为高质量的Maven工件/存储库,在一个即时的、简单的Gradle构建中(即DRY)。

因此:拥有一个根项目作为保护伞,它定义并包含所有公共配置(实际上除了真正的依赖项之外的所有配置)。

我将当前的“结果”移植到Github上的一个示例项目中,并已经在Gradle论坛上提出了这个问题。

目前,我没有声明必要的任务,以便在中央构建中提供标准的-sources-javadoc工件。

例如,在寻找基于Kotlin DSL的解决方案时,您会发现这三个“解决方案”在多模块方案中都不再起作用:

  • https://stackoverflow.com/A/48070667
  • https://stackoverflow.com/A/52596969/1237653
  • 甚至官方的“Maven Publish”文档也只能在单模块场景中工作。

完整示例参见GitHub:https://github.com/bentolor/gradle-maven-multimodule-kotlindsl

subprojects {
    apply(plugin = "java-library")
    apply(plugin = "maven-publish")
    group = "de.bentolor.sampleproject"
    version = "0.1.0"

    repositories {
        jcenter()
    }

    dependencies {
        // Dependencies used in EVERY module
        "compile"("commons-logging:commons-logging:1.2")
        "testImplementation"("junit:junit:4.12")
    }

    tasks {
        // not working
        /*register("sourcesJar", Jar::class.java) {
            from(sourceSets.main.get().allJava)
            classifier = "sources"
        }*/

       // not working, eiher
       /* task<Jar>("sourcesJar") {
            from(sourceSets.main.get().allJava)
            classifier = "sources"
       } */
    }

    configure<JavaPluginExtension> {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }

    configure<PublishingExtension> {
        publications {
            create<MavenPublication>(project.name) {
                from(components["java"])
                // won't work, beause inaccessible declaration in `tasks{}`-Block
                //add("archives", javadocJar)
                //add("archives", sourcesJar)
            }
        }

        repositories {
            mavenLocal()
        }
    }
}
group = "de.bentolor.sampleproject.module2"

dependencies {
    compile(project(":module1"))
}

共有1个答案

刘子实
2023-03-14

试试看:

subprojects {
    apply<JavaLibraryPlugin>()
    apply<MavenPublishPlugin>()

    group = "de.bentolor.sampleproject"
    version = "0.1.0"

    repositories {
        jcenter()
    }

    dependencies {
        val implementation by configurations
        val testImplementation by configurations

        implementation("commons-logging:commons-logging:1.2")
        testImplementation("junit:junit:4.12")
    }

    // This will work, but as long as these tasks are need only for publishing you can declare them inplace later where you need 
    // tasks {
    //     val sourcesJar by creating(Jar::class) {
    //         val sourceSets: SourceSetContainer by project
    //         from(sourceSets["main"].allJava)
    //         classifier = "sources"
    //     }
    //     val javadoc by getting(Javadoc::class)
    //     val javadocJar by creating(Jar::class) {
    //         from(javadoc)
    //         classifier = "javadoc"
    //     }
    // }

    configure<JavaPluginExtension> {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }

    configure<PublishingExtension> {
        publications {
            create<MavenPublication>(project.name) {
                from(components["java"])

                // If you configured them before
                // val sourcesJar by tasks.getting(Jar::class)
                // val javadocJar by tasks.getting(Jar::class)

                val sourcesJar by tasks.creating(Jar::class) {
                    val sourceSets: SourceSetContainer by project

                    from(sourceSets["main"].allJava)
                    classifier = "sources"
                }
                val javadocJar by tasks.creating(Jar::class) {
                    from(tasks.get("javadoc"))
                    classifier = "javadoc"
                }

                artifact(sourcesJar)
                artifact(javadocJar)
            }
        }
    }
}

一些注意事项:

  • 当可以执行类型安全的apply () 时,为什么要使用基于字符串apply
  • 在可以使用委托的情况下,为什么要在依赖项中的sting上使用调用,这样做更不麻烦,可重构性更好。
  • 考虑使用实现而不是编译
  • 父项目在子项目之前计算,因此在父项目中不知道子项目的扩展。
  • 应用于父级和子级的插件集是不同的,您需要在父级中使用子级访问器。

sourcesets是Kotlin DSL为儿童生成的访问器之一。但它在父母版中是不可用的。您可以自己尝试一下:在子项目中只应用Java插件。sourceset将在子生成脚本中可用,但在父生成脚本中不可用。

这也是为什么您可以在子级中使用java,但在父级中配置时必须使用configure 的原因。

但您可以使用委托获取域对象的引用,如任务、源集、配置等。

 类似资料:
  • 我有一个简单的Maven项目,看起来像这个项目视图 有一个主要的pom。xml如下所示: 有两个模块-核心和测试。核心模块pom.xml: 测试模块pom。xml 我想使用核心内部测试的代码。这种依赖性看起来是正确的。该项目已生成,没有错误: 但是,当我在测试中尝试从core导入一个类时,找不到该类。

  • 关于maven项目结构,我有两个问题: 1)我正在创建一个maven多模块项目,并且想知道是否可以将模块的所有公共依赖项放在父POM中?这是正确的做法吗? 2)如果我正在创建一个包含所有web.xml和JSP文件的maven webapp项目,那么web控制器、侦听器和模型对象应该驻留在哪里?在一个单独的maven jar项目中还是在同一个webapp项目中?

  • 我曾广泛使用过Maven 目前有5个不同的maven项目,每个项目都有一个不同的pom.xml。到目前为止,它们之间存在依赖关系,如果需要,每一个都指向 中的另一个。 现在我们不喜欢的是 当我们发布子projectA时,我们需要手动修改所有将projectA作为依赖项的项目以使用新版本。Saw Maven有一个版本插件,不知道这会有什么帮助。 作为解决方案,我希望在POM之间有一个更干净的组织,并

  • 我有一个多模块maven应用程序,我们需要通过Jenkins构建。项目结构如下: 现在,mvn清洁安装-fa.xml工作正常。为此,我创建了一个詹金斯的工作。现在,和a.xml一样,我有另一个项目b.xml.b.xml有和a.xml相同的代码,除了不同的Ids。所以,我又为詹金斯创造了一份工作b.xml.两份工作都很好。但是,现在我想根据我们在Git中提交的项目,从单个Jenkins工作中构建这两

  • 我有以下Maven项目结构: i、 e.Project1、Project2和Project3在目录结构上是对等的,它们都是Spring Boot应用程序(JAR)。我想将Project2和Project3视为Project1的子项,而不改变目录结构。当我在父项目上执行相同的maven命令时,我需要在子项目上过渡地执行所有maven命令。而且最重要的是,我应该能够将它们打包到一个JAR文件中。我在谷

  • 问题内容: 这是一个基本问题,我只是不太熟悉Maven多模块结构。说,我有一个Web应用程序。我想将一些模块连接到它(某些服务)。我是否需要仅将其中一个模块(依赖于其他模块)制作为一个Web应用程序,然后运行它?一开始我以为我可以运行整个项目,但是这个选项在我的IDE中是无效的(我现在正在使用NetBeans),这使我认为我应该运行一个类似于主模块的东西(在这种情况下为Web应用程序) )。是这样