簡體   English   中英

運行生成的 jar 文件時,如何使 Apache Derby 數據庫正常工作?

[英]How can I make my Apache Derby database work when I run my generated jar file?

我創建了一個 JavaFX 應用程序,並生成了一個將啟動的 Jar 文件(使用 Gradle 生成)。

當應用程序啟動時,它不會連接到嵌入式數據庫。 我覺得好像我錯過了一些非常簡單的東西,但經過大量研究,我一直無法弄清楚。 從命令提示符運行 jar 文件時,出現以下錯誤:java.lang.ClassNotFoundException: org.apache.derby.jdbc.EmbeddedDriver

從我所做的閱讀中,我知道我可以將它添加到我的類路徑中,但是在多次嘗試后我沒有成功,我已經讓這個應用程序在另一台計算機上運行。 可能的,對吧?

如果可能的話,我很想更改我的 build.gradle 文件中的某些內容,或者將 .jar 包含在一個文件夾中或類似的東西中,這將使運行程序的人變得簡單。 程序大小不是幾個千兆字節的問題。

你有兩個問題

  • 驅動程序類不在您的應用程序 jar 中
  • 如果您將該數據庫嵌入到應用程序 jar 中,您將無法寫入它

你可以做一個“胖罐子”,但這不會解決第二個問題。 您確實需要制作一個安裝程序來執行此操作,以便將 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設置模塊--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用戶指南 有一些 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 應用程序。 您可能還想閱讀此問答

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM