JAR (Java Archive) 檔案格式基於流行的 ZIP 格式,用於將多個檔案打包成單一檔案。不同於一般壓縮檔,JAR 不僅用於壓縮與發布,更支援函式庫、元件與外掛程式的組織與封裝,可被編譯器、JVM 等工具直接使用。JAR 內包含特殊檔案(如 Manifest、簽名檔),指示工具如何處理特定 JAR。
預設 jar 工具會壓縮檔案。非壓縮 JAR 載入較快(無需解壓),但網路傳輸時間較長。
大多數 JAR 包含 META-INF 目錄,儲存套件與擴充的設定資料(安全性、版本資訊)。Java 2 平台辨識以下檔案:
MANIFEST.MF:定義擴充與套件相關資料INDEX.LIST:jar -i 產生,包含應用程式/擴充中定義套件的位置資訊,供類別載入器加速載入*.SF:JAR 簽名檔*.DSA:簽名區塊檔,儲存簽名 JAR 所用的公開金鑰| 功能 | 指令 |
|---|---|
| 用單一檔案建立 JAR | jar cf jar-file input-file... |
| 用目錄建立 JAR | jar cf jar-file dir-name |
| 建立非壓縮 JAR | jar cf0 jar-file dir-name |
| 更新 JAR | jar uf jar-file input-file... |
| 檢視 JAR 內容 | jar tf jar-file |
| 解壓 JAR 所有內容 | jar xf jar-file |
| 解壓特定檔案 | jar xf jar-file archived-file... |
| 執行可執行 JAR | java -jar app.jar |
可執行 JAR 是自包含的 Java 應用程式,經特殊設定後可直接由 JVM 執行,無需先解壓或設定類別路徑。
manifest 檔案,加入一行:Main-Class: com.mycompany.myapp.Samplejar cmf manifest ExecutableJar.jar application-dirjava -jar ExecutableJar.jar 執行可執行 JAR 的 Manifest 必須透過 Class-Path 標頭引用所有相依 JAR。使用 -jar 選項時,環境變數 CLASSPATH 與命令列指定的類別路徑會被 JVM 忽略。
在 Manifest 中為套件加入 Name 標頭(以 / 結尾)與 Sealed: true,即可密封該套件。若嘗試從該 JAR 以外載入密封套件中的類別,JVM 會拋出 SecurityException。
擴充功能透過 Manifest 的 Class-Path 標頭指定所需的其他 JAR。JVM 載入使用擴充機制的 JAR 時,會自動將 Class-Path 引用的 JAR 加入類別路徑(路徑為相對路徑,通常需置於同一目錄)。
JAR 可用 jarsigner 工具或 java.security API 簽名。簽名後 Manifest 會更新,META-INF 新增簽名檔 (.SF) 與簽名區塊檔 (.DSA/.RSA)。
私鑰與公開金鑰憑證存於受密碼保護的 Keystore 資料庫中,每個項目由唯一別名存取。使用 keytool -genkey 產生金鑰對並加入 Keystore。
# 簽名
jarsigner -keystore jamesKeyStore -storepass jamesKeyStorePass \
-keypass jamespass -signedjar SSample.jar Sample.jar james
# 驗證
jarsigner -verify SSample.jar
JDK 1.3+ 支援 JAR 索引優化網路應用程式/Applet 的類別搜尋。jar -i 建立 INDEX.LIST,儲存於根 JAR 的 META-INF 中,類別載入器下載第一個 JAR 後即可高效定位所需類別所在的 JAR,避免線性搜尋造成的頻寬浪費與啟動延遲。
JAR 格式遠超單純壓縮格式,其內建於核心平台(編譯器、類別載入器)的豐富功能,能顯著提升 Java 應用程式的效率、安全性與組織性。善用 JAR 特性,可簡化開發與部署流程。