问题
Gradle 所做的部分工作是依赖管理。这意味着它知道您需要哪些依赖项以及如何找到它们(基于构建脚本中的配置)。当您通过 Gradle 执行/构建应用程序时,该工具将自动搜索存储库、下载+缓存依赖项,并将这些依赖项放在类路径/模块路径中。部署 JAR 文件后,Gradle 将不再涉及,因此您的部署负责包含所需的依赖项。
换句话说,您需要将应用程序的依赖项与应用程序 JAR 文件一起提供。
解决方案
您基本上只需要确保在您的应用程序中包含应用程序的依赖项。这里至少有三种方法可以做到这一点。
复制依赖项
作为构建过程的一部分,将依赖项复制到构建文件夹中。以下是此类任务的示例,使用 Kotlin DSL:
tasks {
val jar by existing(Jar::class)
val copyDependencies by registering(Copy::class) {
from(configurations.runtimeClasspath)
into(jar.get().destinationDirectory)
}
jar.configure {
finalizedBy(copyDependencies)
}
}
现在,如果您执行./gradlew jar,Gradle 将创建 JAR 文件,然后将依赖项复制到与 JAR 文件相同的目录中。然后你只需要确保所有的 JAR 文件都部署在一起。
如果我没记错的话,默认的类路径是工作目录。但是要指定类路径,您将在执行应用程序时使用-cp、-classpath 或--class-path。如果需要,可以使用-p 或--module-path 设置模块路径。
胖罐子
创建一个所谓的“胖”或“超级”JAR 文件。这是一个 JAR 文件,不仅包含您自己的应用程序代码,还包含您应用程序的所有依赖项。您可以为此配置jar 任务,但简单地应用Gradle Shadow Plugin 可能会更容易。
// Kotlin DSL
plugins {
id("com.github.johnrengelman.shadow") version "<version>"
// other plugins...
}
然后您将使用./gradlew shadowJar 创建胖 JAR。有关详细信息,请参阅用户指南。
自包含应用程序
使用jpackage 之类的工具创建一个独立的可执行文件。该工具为您提供了一个嵌入了所有代码和 JRE 的应用程序,然后为您提供了安装程序或本机可执行文件(例如 Windows 上的exe)。这是jpackage 的user guide。 Gradle 插件可以让您更轻松地使用来自 Gradle 的 jpackage,例如 The Badass JLink Plugin。
注意jpackage 是在 Java 14 中添加的,并且一直孵化到 Java 16。还要注意 jpackage 不能“跨包”。也就是说,如果您在 Windows 上构建应用程序,那么您只能为 Windows 创建安装程序/可执行文件; MacOS 和 Linux 相同。如果您需要为多个平台打包,那么您需要访问每个平台。
JavaFX
由于您已使用 JavaFX 标记此问题,因此我想提醒您注意。虽然如果您没有使用 JavaFX 9+,那么这与您无关。
从技术上讲,JavaFX 仅支持作为 命名 模块加载。这意味着它需要通过--module-path 或通过将其包含在jlink / jpackage 构建的自定义运行时映像中来放置在模块路径上。从 JavaFX 16 开始,如果从 未命名 模块(即类路径)加载 JavaFX,则会发出警告。
可执行的 JAR 文件放置在类路径中。这包括胖 JAR。如果你没有使用包含 JavaFX 的 JDK——这意味着你有 Gradle 拉入 JavaFX 依赖项——那么 JavaFX 将被包含在你的胖 JAR 中并被放置在类路径中。现在,尽管不受支持并且现在发出警告,但如果 JavaFX 在类路径上,目前似乎没有任何问题。除了一个警告:您的主类不能是javafx.application.Application 的子类。您必须创建一个单独的主类来简单地启动 JavaFX。
正因为如此,我强烈推荐使用jpackage 来部署JavaFX 应用程序。您可能还想阅读this Q&A。