如何解决运行生成的 jar 文件时,如何使 Apache Derby 数据库正常工作?
我创建了一个 JavaFX 应用程序,并生成了一个将启动的 Jar 文件(使用 Gradle 生成)。
当应用程序启动时,它不会连接到嵌入式数据库。我觉得好像我错过了一些非常简单的东西,但经过大量研究,我一直无法弄清楚。从命令提示符运行 jar 文件时,出现以下错误: java.lang.classNotFoundException: org.apache.derby.jdbc.EmbeddedDriver
从我所做的阅读中,我知道我可以将它添加到我的类路径中,但经过多次尝试后我没有成功,我已经让这个应用程序在另一台计算机上运行。这是可能的,对吧?
如果可能的话,我很想更改我的 build.gradle 文件中的某些内容,或者将 .jar 包含在一个文件夹中或类似的东西中,这将使运行程序的人变得简单。程序大小不是几个 GB 的问题。
解决方法
你有两个问题
- 驱动程序类不在您的应用程序 jar 中
- 如果您将该数据库嵌入到应用程序 jar 中,您将无法对其进行写入
你可以制作一个“胖罐子”,但这并不能解决第二个问题。您确实需要使 an installer 执行此操作,以便将 db 保留在文件系统中,以便将其写入。
,问题
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
设置。
胖罐
创建所谓的“fat”或“uber”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——这意味着您在 JavaFX 依赖项中有 Gradle 拉取——那么 JavaFX 将包含在您的胖 JAR 中并放置在类路径中。现在,尽管不受支持并且现在发出警告,但如果 JavaFX 在类路径上,目前似乎没有任何问题。除了一个警告:您的主类不能是 javafx.application.Application
的子类。您必须创建一个单独的主类来简单地启动 JavaFX。
因此,我强烈建议使用 jpackage
来部署 JavaFX 应用程序。您可能还想阅读this Q&A。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。