使用Gradle Kotlin DSL Jar.from() [英] Use of Gradle Kotlin DSL Jar.from()

查看:134
本文介绍了使用Gradle Kotlin DSL Jar.from()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这似乎是一种反模式,因为基本机制可以推断或偏爱我应该将它们分别放置在不同的sourceSet中. gh.

随意阅读文档暗示Jar.from()可能以这种方式有用:指定 source 文件或目录..."

事实证明,源"可能有点用词不当.这是一个示例,一个典型的kotlin胖子罐,添加了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(),但我找不到找到解决方法.根据IntelliJ get()返回一个相当不透明的"Provider "在实际的Javadoc中找不到: 1 2 ,我真的感觉我正沿着花园小径走去,周围的树林迅速变得越来越黑.

这不应该那么复杂.

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

解决方案

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

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

好吧,文档还不止于此,而是说要复制并创建一个子级CopySpec".因此,它不是 source 中的 source ,而是复制操作的 source .在Gradle中,创建档案(ZIP,JAR)的任务与复制文件的任务共享其API,因为创建档案可以看作是将文件从其源位置复制到目标位置(在档案内部).

因此,from方法可用于指定要复制/存档的文件.但是它不仅需要一个sourcePath参数,而且还需要一个闭包或配置操作.使用第二个参数,您可以将源文件或目录缩小到所需的一个文件,例如,使用方法 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) } }) }

I'm trying to include a single source file for the Main-Class of a jar -- actually I have a toplevel directory of such files, demo/, but I don't want them all in a jar. I want separate jars, each using only one of these.

This seems like sort of an anti-pattern in gradle, as the fundamental mechanism infers or prefers that I should instead place each in a distinct sourceSet. Ugh.

A casual reading of the docs implies Jar.from() might be useful this way: "Specifies the source files or directories..."

As it turns out, "source" is perhaps a bit of a misnomer. Here's an example, a typical kotlin fat jar with the added 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) }
    })
}         

Forgive my naivety: Guess what does not end up in the jar? LockingBufferDemo.class. Guess what does? LockingBufferDemo.kt. In other words, this is treated more like a resource, not a source, and what would have been the simplest answer is a dead end.

Another way to approach this would be add the demo directory as an independent sourceSet and then use from(sourceSets["demo"].get(), except I can't find a way to complete that; according to IntelliJ get() returns a rather opaque "Provider" which I can't find mentioned in the actual javadoc: 1, 2 and I really feel like I'm heading down the garden path at this point with the woods rapidly growing darker around me.

This should not be this complicated.

How can I add a single file (or class derived from such) into a jar in gradle without having to put it alone in a directory and create a sourceSet for every such directory?

解决方案

Regarding your explanations at the start of your post, you should consider creating multiple tasks of type Jar on your own, as every task of type Jar will only create a single JAR-file, and you "want separate jars". I do not think you should use different source sets, as all of the files are Java Kotlin source files in the end and are processed in the same way (compilation, tests, docs ...). Multiple source sets would complicate this common pipeline.

"Specifies the source files or directories..." As it turns out, "source" is perhaps a bit of a misnomer.

Well, the documentation does not stop there, but it says "for a copy and creates a child CopySpec". So it is not the source as in source code, but the source of a copy operation. In Gradle, tasks that create an archive (ZIP, JAR) share their API with tasks that copy files, as the creation of an archive can be seen as copying files from their source location to their target location (inside the archive).

So, the from method can be used to specify the files that are copied / archived. But it does not only take a sourcePath parameter, but also a closure or action for configuration. Using this second parameter, you can narrow your source files or directories down to the one file you need, for example using the method 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) }
    })
}

这篇关于使用Gradle Kotlin DSL Jar.from()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆