Gradle 和 Shadow 插件 - 在 shadowJar 任务之后将附加文件(.jar 文件)复制到最终 jar
Posted
技术标签:
【中文标题】Gradle 和 Shadow 插件 - 在 shadowJar 任务之后将附加文件(.jar 文件)复制到最终 jar【英文标题】:Gradle and Shadow plugin - copy additional files (.jar files) to final jar after shadowJar task 【发布时间】:2019-03-02 20:16:24 【问题描述】:问题描述:
我正在使用 Gradle Shade 插件,一切正常,并将资源文件复制到最终的 jar 中。但是,正如docs 所说,它不能将其他.jar
文件包含为资源,因为它无法将它们与依赖项区分开来。它会解开它们而不是。
我想做的事:
我想将tools
文件夹(位于我的build.gradle
旁边)中的额外.jar
文件复制到由shadowJar
任务生成的最终jar
中。
问题:
如何扩展任务 (shadowJar
) 以将其他文件复制到生成的 jar 文件中。
【问题讨论】:
我认为您需要更准确地提出问题。您想将其他 JAR 按原样 复制到影子 JAR(即 JAR 中的 JAR 文件)还是要将其他 JAR 的 内容 复制到影子 JAR ? 我认为这个问题准确地说明了我能够复制任何其他资源,除了 jar 文件。 “jar 文件的内容”算作“其他资源”。问题是关于在一个胖罐子里复制额外的罐子。 我了解您的问题“是关于在胖罐中复制额外的罐子”。关键是,您可以通过两种方式将 JAR(例如j
)复制到 Uber JAR(例如 u
)中:将 j
的内容解压缩并复制到 u
(通常保留文件夹结构,此外还可能合并META-INF/services
文件),或者j
被按原样 复制到u
中(即文件本身以解压缩的方式)。
@twwt 这就是我想告诉你的。用你的术语来说,我想将一个 jar J
复制到 uber jar U
按原样(不拆包)。问题的“问题描述”部分也说明了这一点 - 它说 shadowJar 解压罐子,而不是逐字复制。我希望 shadowJar
任务将 jar example.jar
从 some/path/example.jar
varbatim 复制到 target/app-uberjar.jar
。
【参考方案1】:
Gradle shadow 插件的文档Embedding Jar Files Inside Your Shadow Jar 部分对此进行了回答:
[...] shadow 无法区分配置为依赖项的 jar 文件和资源文件夹中包含的 jar 文件。这意味着在资源目录中找到的任何 jar 都将像任何其他依赖项一样合并到影子 jar 中。如果您打算将 jar 嵌入其中,则必须在影子任务开始之前将 jar 重命名为不以 .jar 结尾。
不幸的是,这既适用于作为依赖项配置一部分的 JAR,也适用于使用 from
复制规范复制 JAR(因为 shadowJar
任务扩展了 @ 987654324@ 任务;这又是一个复制任务,因此支持复制规范)。
因此,只能通过重命名来嵌入 JAR。如果必须在 Uber JAR 中将其命名为 .jar
,我认为唯一的选择是三步解决方法:
-
创建 Uber JAR 并通过重命名嵌入 JAR;例如,使用后缀
*.zip
。
shadowJar
from("$dirThatContainsSomeJARs")
include '*.jar'
rename '(.+).jar', '$1.zip'
-
解压 Uber JAR 并将所有已嵌入的 JAR 重命名为
*.zip
重新命名为 *.jar
。
使用jar
或zip
任务重新打包所有内容。
【讨论】:
以上是关于Gradle 和 Shadow 插件 - 在 shadowJar 任务之后将附加文件(.jar 文件)复制到最终 jar的主要内容,如果未能解决你的问题,请参考以下文章
使用Gradle Application Plugin插件自动生成可执行.sh和.bat启动脚本
无法在 Intellij 中为 Gradle 导入 ShadowJar 插件