首页 > 解决方案 > Gradle Kotlin DSL Jar.from() 的使用

问题描述

我正在尝试为 jar 包含一个源文件Main-Class——实际上我有一个此类文件的顶级目录demo/,但我不希望它们都在一个 jar 中。我想要单独的罐子,每个罐子只使用其中一个。

这似乎是 gradle 中的一种反模式,因为基本机制推断或更喜欢我应该将每个都放在不同的sourceSet. 啊。

随便阅读一下文档意味着Jar.from()这样可能会有用:“指定文件或目录......”

事实证明,“来源”可能有点用词不当。这是一个示例,一个典型的 kotlin fat jar 添加了from("demo/LockingBufferDemo.kt")

val jar by tasks.getting(Jar::class) {
    manifest { attributes["Main-Class"] = "LockingBufferDemoKt" }
    from(sourceSets.main.get().output)
    from("demo/LockingBufferDemo.kt")
    dependsOn(configurations.runtimeClasspath)
    from({
        configurations.runtimeClasspath.get().filter {
            it.name.endsWith("jar") }.map { zipTree(it) }
    })
}         

原谅我的天真:猜猜罐子里没有什么? LockingBufferDemo.class. 猜猜有什么作用?LockingBufferDemo.kt. 换句话说,这更像是一种资源,而不是一种来源,最简单的答案是死胡同。

解决此问题的另一种方法是将demo目录添加为独立目录sourceSet,然后使用from(sourceSets["demo"].get(),除非我找不到完成该目录的方法;根据 IntelliJget()返回一个相当不透明的“提供程序”,我在实际的 javadoc 中找不到它:12,我真的觉得我现在正沿着花园小路前进,周围的树林迅速变暗。

这不应该这么复杂。

如何将单个文件(或从此类派生的类)添加到 gradle 中的 jar 中,而不必将其单独放在目录中并sourceSet为每个这样的目录创建一个?

标签: kotlingradleexecutable-jar

解决方案


关于您在帖子开头的解释,您应该考虑Jar自己创建多个类型的任务,因为每个类型的任务Jar只会创建一个 JAR 文件,并且您“想要单独的 jars”。我认为您不应该使用不同的源集,因为所有文件最终都是Java Kotlin 源文件并且以相同的方式处理(编译、测试、文档......)。多个源集会使这个通用管道复杂化。

“指定源文件或目录...” 事实证明,“源”可能有点用词不当。

好吧,文档并不止于此,但它说“复制并创建一个孩子CopySpec”。所以它不是代码中的源,而是复制操作的。在 Gradle 中,创建存档(ZIP、JAR)的任务与复制文件的任务共享其 API,因为存档的创建可以被视为将文件从源位置复制到目标位置(存档内部)。

因此,该from方法可用于指定被复制/归档的文件。但它不仅需要一个sourcePath参数,还需要一个闭包或操作来进行配置。使用第二个参数,您可以将源文件或目录缩小到您需要的一个文件,例如使用方法include

val jar by tasks.getting(Jar::class) {
    manifest { attributes["Main-Class"] = "LockingBufferDemoKt" }
    from(sourceSets.main.get().output) {
        include("**/LockingBufferDemo.class")
    }
    dependsOn(configurations.runtimeClasspath)
    from({
        configurations.runtimeClasspath.get().filter {
            it.name.endsWith("jar") }.map { zipTree(it) }
    })
}

推荐阅读