在运行生成的jar文件时,如何使ApacheDerby数据库正常工作



我创建了一个JavaFX应用程序,并生成了一个将启动的Jar文件(使用Gradle生成)。

当应用程序启动时,它不会连接到嵌入式数据库。我觉得我错过了一些非常简单的东西,但经过大量的研究,我还是没能弄清楚。在命令提示符下运行jar文件时,我得到以下错误:java.lang.ClassNotFoundException:org.apache.derby.jdbc.EmbeddedDriver

从我所做的阅读中,我知道我可能可以将其添加到我的类路径中,但在多次尝试后,我都没有成功,我已经让这个应用程序在另一台计算机上运行。这是可能的,对吧?

如果可能的话,我很想更改build.gradle文件中的一些内容,或者将.jar放在一个文件夹中,或者类似的东西,让运行程序的人更容易。程序大小不是一个问题,缺少几GB。

有两个问题

  • 驱动程序类不在您的应用程序jar中
  • 如果你将数据库嵌入到应用程序jar中,你将无法对其进行写入

你可以做一个"肥罐子",但这不会解决第二个问题。你真的需要制作一个安装程序来完成这项工作,以便将数据库留在文件系统中,以便将其写入

问题

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

创建一个所谓的";脂肪;或";uber";JAR文件。这是一个JAR文件,它不仅包括您自己的应用程序代码,还包括您应用程序的所有依赖项。您可以为此配置jar任务,但可能更容易简单地应用渐变阴影插件。

// Kotlin DSL
plugins {
id("com.github.johnrengelman.shadow") version "<version>"
// other plugins...
}

然后用./gradlew shadowJar创建胖JAR。有关详细信息,请参阅用户指南。

自给自足的应用

使用类似jpackage的工具创建一个自包含的可执行文件。该工具为您提供一个嵌入了所有代码和JRE的应用程序,然后为您提供安装程序或本机可执行文件(例如,Windows上的exe)。这是jpackage的用户指南。有一些Gradle插件可以让使用Gradle的jpackage变得更容易,比如Badass JLink插件。

注意,jpackage是在Java 14中添加的,并且一直培育到Java 16。还要注意,CCD_;交叉包装";。也就是说,如果你在Windows上构建应用程序,那么你只能为Windows创建安装程序/可执行文件;MacOS和Linux也是如此。如果你需要为多个平台打包,那么你需要访问每个平台。


javafx

既然你已经用JavaFX标记了这个问题,我想提醒你一点。尽管如果你没有使用JavaFX9+,那么这与你无关。

从技术上讲,JavaFX只支持作为命名的模块加载。这意味着它需要通过--module-path或通过将其包含在jlink/jpackage构建的自定义运行时映像中来放置在模块路径上。从JavaFX 16开始,如果JavaFX是从未命名的模块(即类路径)加载的,则会发出警告。

可执行JAR文件被放置在类路径上。这包括丰厚的JAR。如果您没有使用包含JavaFX的JDK,也就是说您在JavaFX依赖项中有Gradle pull,那么JavaFX将包含在您的胖JAR中,并放置在类路径上。现在,尽管不受支持,并且现在发出警告,但如果JavaFX在类路径上,则当前似乎没有任何中断。除了一个警告:您的主类不能是javafx.application.Application的子类。您必须创建一个单独的主类来启动JavaFX。

正因为如此,我强烈建议使用jpackage来部署JavaFX应用程序。你可能想阅读这个问答;A也是。

最新更新