Java 打包準則 - Arch Linux 中文维基

跳至內容

# Java 打包準則

出自 Arch Linux 中文维基
翻譯狀態：

- 本文（或部分內容）譯自 Java package guidelines，最近一次同步於 2024-07-08，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

Arch 打包準則

32 位 – 安全 – CLR – CMake – DKMS – Eclipse – Electron – Free Pascal – GNOME – Go – Haskell – Java – 交叉編譯工具 – KDE – Lisp – Meson – MinGW – 內核模塊 – Node.js – Nonfree – OCaml – Perl – PHP – Python – R – Ruby – Rust – Shell – VCS – Web – Wine – 字體

這篇文章或章節的翻譯質量不佳。

原因：可能大量使用了機器翻譯，有部分翻譯不準確或錯誤，需要重新校對或翻譯（在 Talk:Java 打包準則# 中討論）

本文檔定義了 Arch Linux 下打包 Java 程序的建議標準。Java 程序是出了名的難以在沒有重疊的依賴關係的情況下乾淨利落地打包。本文檔描述了一種處理這種情況的方法。這些指南十分靈活，以涵蓋處理 Java 程序時遇到的許多不同情況。

## 介紹

Arch Linux 的打包人員似乎無法就如何處理 Java 包達成一致。官方和非官方軟體庫以及 AUR 的 PKGBUILD 中使用了各種方法。這包括把所有東西扔到 `/opt` 裡，把 Shell 腳本放在 `/usr/bin` 或把配置文件放在 `/etc/profile` 中。其他的則是放在 `/usr/share` 目錄中，腳本放在 `/usr/bin` 中。許多做法在系統 `CLASSPATH` 和 `PATH` 中添加了不必要的文件。

## 典型 Java 應用程式的結構

大多數桌面 Java 應用程式結構類似。它們是由一個不依賴系統（但依賴軟體包！）的安裝程序安裝的。這通常會把所有東西都安裝在包含 `bin`、`lib`、`jar`、`conf`等子目錄的目錄下。一般會有一個包含主要可執行類的主 jar 文件。通常還會提供一個 Shell 腳本來運行主類，這樣用戶就不必直接調用 Java 解釋器。這個 Shell 腳本通常相當複雜，因為它需要在不同的發行版中通用，而且經常包括不同系統的特殊情況（例如 Cygwin）。

`lib` 目錄通常包含捆綁的 jar 文件來滿足 Java 程序的依賴。這使用戶安裝程序變得簡單（其中包含了所有依賴），但卻是軟體包開發者的噩夢。幾個軟體包捆綁相同的依賴會浪費空間。這在過去並不是一個大問題，當時桌面 Java 應用程式和庫較少，而那些存在的應用程式和庫本身往往也非常大。但現在情況不同了……

運行程序所需的其他文件通常與主 jar 文件存放在同一目錄或其子目錄下。由於 Java 程序不知道它們的類是從哪裡加載的，所以通常需要在這個目錄中運行（即 Shell 腳本應 `cd` 進入該目錄），或者設置一個環境變量來指示這個目錄的位置。

## 在 Arch Linux 中打 Java 包

在 Arch 中打包 Java 應用程式將會比現在更費勁。然而，這是值得的，它可以使文件系統更乾淨，捆綁的依賴更少（隨著越來越多的Java 庫被重構為單獨的包，打包會變得更容易）。在創建 Arch Linux Java 包時，應遵循以下準則：

- 如果 Java 庫有一個通用的名字，那麼包的名字應該在前面加上 `java-` 以與其他庫區分。對於命名獨特的包（如 JUnit）、終端用戶程序（如 Eclipse）或可以用其他前綴唯一描述的庫（如 jakarta-commons-collections 或 apache-ant），則不需要這樣做。

- 將所有隨程序分發的 jar 文件（而不是其他文件）放在 `/usr/share/java/程序`目錄下。這包括隨程序分發的所有依賴 jar 文件。然而，應該努力將常見的或大型的依賴放到單獨的包中。這只有在程序不依賴某個特定版本的庫時才能實現。

  這個規則使得迭代重構依賴關係成為可能。也就是說，軟體包和它的所有依賴可以先放在一個目錄中。經過測試後，主要的依賴可以一個一個地被重構出來。請注意，有些應用程式在主 jar 文件中包括捆綁的依賴。也就是說，他們將捆綁的依賴解包，並將其包含在主 jar 中。這樣的依賴通常非常小，重構它們沒有什麼意義。

- 如果程序是要由用戶運行的，編寫一個自定義的 Shell 腳本運行主 jar 文件。這個腳本應該放在 `/usr/bin` 中。庫一般不需要 Shell 腳本。從頭開始編寫 Shell 腳本，不要使用程序捆綁的腳本。刪除檢查自定義環境（如 Cygwin）的代碼，以及試圖確定 `JAVA_HOME` 是否已經設置的代碼（Arch 不使用 `JAVA_HOME`，而是使用 `archlinux-java` 來設置 `/usr/bin/java` 符號連接）。

  尋找 jar 文件的腳本應該類似這樣：

      #!/bin/sh
      exec /usr/bin/java -jar '/usr/share/java/程序/程序.jar' "$@"

  尋找單個類文件的應該類似這樣：

      #!/bin/sh
      exec /usr/bin/java '/usr/share/java/程序/程序類名' "$@"

- 使用 `-cp` 選項為 Java 解釋器設置 `CLASSPATH`，除非有明確的理由不這樣做（即：`CLASSPATH` 用於插件機制）。`CLASSPATH` 應該包括 `/usr/share/java/程序`目錄下的所有 jar 文件，以及已被重構到其他目錄中的依賴庫的 jar 文件。可以使用類似以下代碼：

      for name in /usr/share/java/程序/*.jar ; do
        CP=$CP:$name
      done
      CP=$CP:/usr/share/java/dep1/dep1.jar
      java -cp $CP 程序.java.MainClass

- 確保 Shell 腳本可執行！

- 隨軟體包一起分發的其他文件應存放在 `/usr/share` 下以該軟體包命名的目錄中。你可能需要在 Shell 腳本中的 `項目_HOME` 等變量中設置該目錄的位置。本準則假設程序希望所有文件都在同一目錄下（這是 Java 軟體包的標準做法）。如果配置文件更適合放在其他地方（例如，把日誌放在 `/var/log` 中），則可以這樣做。

  請記住，在某些系統上 `/usr` 可能被掛載為只讀。如果應用程式需要寫入共享目錄中的文件，它們可能需要被重新定位到`/etc`、`/var` 或用戶的主目錄。

- 與其他 Arch Linux 軟體包的標準一樣，如果遵守上述標準需要做大量的工作，則應以其偏好的方式安裝軟體包，並將生成的目錄放在 `/opt` 中。這對於捆綁 JRE、包含自定義版本的依賴或做其他奇怪和痛苦的事情的程序很有用。

### 多個API實現

如果軟體包分發了常用的 API 實現（比如 jdbc 驅動），則應該把庫放在 `/usr/share/java/API_名稱` 下。這樣，允許用戶選擇實現的應用程式會知道在哪裡尋找它們。這個位置只用於庫包本身。如果這樣的實現是應用程式分發的一部分，不要將這個 jar 文件放在公共位置，而是使用普通的包結構。

### 目錄結構示例

為了說明問題，下面是一個假想的名為 `foo` 程序的目錄結構示例。由於 `foo` 是一個常見的名字，所以軟體包被命名為 `java-foo`，但注意目錄結構中並沒有體現：

- `/usr/share/java/foo/`
- `/usr/share/java/foo/foo.jar`
- `/usr/share/java/foo/bar.jar`（`java-foo` 包含的依賴）
- `/usr/share/foo/`
- `/usr/share/foo/*.*`（`java-foo` 需要的一些文件）
- `/usr/bin/foo`（可執行的 Shell 腳本）

### 依賴

Java packages might specify `java-runtime` or `java-environment` as dependency, based on what they need. For most packages, `java-runtime` (Java Runtime Environment) is what is needed to simply run software written in Java. `java-environment` (Java Development Toolkit) is needed by packages that will need to compile Java source code into bytecode.

更多信息參見 Java。

分類：​

- Arch 打包準則

隱藏分類：​

- 使用「模板:糟糕的翻譯」標記的頁面或章節

Java 打包準則
新增話題