多项目Gradle+Kotlin:如何使用Kotlin DSL创建包含所有子项目的Jar



我有一个Gradle项目,有两个子项目。父级不包含任何代码;所有Kotlin代码都在这两个子项目中。所有Gradle构建文件都是在Kotlin DSL中定义的。

构建后,Gradle生成两个JAR文件,一个在每个子项目的build子文件夹中。我相信这是Gradle的默认行为。但这不是我想要的。

我想将父项目的JAR文件作为Maven工件发布。因此,我需要将两个子项目都包含在一个JAR文件中。我怎样才能做到这一点?

注意:在这个网页上,作者似乎在这个代码片段中实现了我所需要的东西:

apply plugin: "java"
subprojects.each { subproject -> evaluationDependsOn(subproject.path)}
task allJar(type: Jar, dependsOn: subprojects.jar) {
baseName = 'multiproject-test'
subprojects.each { subproject ->
from subproject.configurations.archives.allArtifacts.files.collect {
zipTree(it)
}
}
}
artifacts {
archives allJar
}

然而,这是在Gradle的原生Groovy DSL中定义的。我发现自己无法将其翻译成Kotlin DSL。我试图在Kotlin构建文件(*.gradle.kts(之外添加一个Groovy构建文件(*.gradle(,但这导致了一个奇怪的构建错误。我不确定是否支持混合构建文件语言。此外,我也认为这是不好的做法。最好只用一种语言定义所有生成文件。

此外,上面的例子与Java编程语言有关。但我不认为这会是一个大问题,因为Java和Kotlin都会生成JVM字节码作为编译输出。

更多澄清:

  • 我不是在说;胖JAR";。依赖项和Kotlin库而不是应该包含在JAR中
  • 我不在乎子项目的JAR文件是否仍在构建中。我只对包含两个子项目的集成JAR感兴趣
  • 重点是获得二进制文件的组合JAR。源代码和JavaDoc的组合JAR是一个不错的选择,但不是严格要求的

我会使用Gradle指南创建"uber";或";脂肪;以Gradle文档中的JAR为基础。你想要的基本上是一样的。它也比您发现的Groovy示例好得多,因为它没有使用不鼓励使用的subprojectsutil或需要了解其他项目如何配置的"简单共享"。

  1. 创建用于解析其他项目的配置。

    // build.gradle.kts
    val mergedJar by configurations.creating<Configuration> {
    // we're going to resolve this config here, in this project
    isCanBeResolved = true 
    // this configuration will not be consumed by other projects
    isCanBeConsumed = false 
    // don't make this visible to other projects
    isVisible = false 
    }
    
  2. 使用新配置来添加对我们想要添加到组合Jar 中的项目的依赖项

    dependencies {
    mergedJar(project(":my-subproject-alpha"))
    mergedJar(project(":my-subproject-beta"))
    }
    
  3. 现在从文档中复制指南,但我们可以使用mergedJar配置,而不是使用configurations.runtimeClasspath,它只会创建我们指定的子项目。

    然而,我们需要做一些修改。

    1. 我已经调整了这个例子来编辑现有的Jar任务,而不是创建一个新的"fatJar"任务
    2. 由于某种原因,设置isTransitive = false会导致Gradle无法解析。相反,我添加了一个过滤器(it.path.contains(rootDir.path)(,以确保我们正在使用的Jars在项目中
    tasks.jar {
    dependsOn(mergedJar)
    from({
    mergedJar
    .filter {
    it.name.endsWith("jar") && it.path.contains(rootDir.path)
    }
    .map {
    logger.lifecycle("depending on $it")
    zipTree(it)
    }
    })
    }
    

相关内容

最新更新