一
JAR 文件格式以流行的 ZIP 文件格式爲基礎,用於將許多個文件聚集爲一個文件。與 ZIP 文件不同的是,JAR 文件不僅用於壓縮和發佈,而且還用於部署和封裝庫、組件和插件程序,並可被像編譯器和 JVM 這樣的工具直接使用。在 JAR 中包含特殊的文件,如 manifests 和部署描述符,用來指示工具如何處理特定的 JAR。
一個 JAR 文件可以用於:
- 用於發佈和使用類庫
- 作爲應用程序和擴展的構建單元
- 作爲組件、applet 或者插件程序的部署單位
- 用於打包與組件相關聯的輔助資源
JAR 文件格式提供了許多優勢和功能,其中很多是傳統的壓縮格式如 ZIP 或者 TAR 所沒有提供的。它們包括:
- 安全性。可以對 JAR 文件內容加上數字化簽名。這樣,能夠識別簽名的工具就可以有選擇地爲您授予軟件安全特權,這是其他文件做不到的,它還可以檢測代碼是否被篡改過。
- 減少下載時間。 如果一個 applet 捆綁到一個 JAR 文件中,那麼瀏覽器就可以在一個 HTTP 事務中下載這個 applet 的類文件和相關的資源,而不是對每一個文件打開一個新連接。
- 壓縮。JAR 格式允許您壓縮文件以提高存儲效率。
- 傳輸平臺擴展。 Java 擴展框架(Java Extensions Framework)提供了向 Java 核心平臺添加功能的方法,這些擴展是用 JAR 文件打包的(Java 3D 和 JavaMail 就是由 Sun 開發的擴展例子)。
- 包密封。存儲在 JAR 文件中的包可以選擇進行 密封,以增強版本一致性和安全性。密封一個包意味着包中的所有類都必須在同一 JAR 文件中找到。
- 包版本控制。一個 JAR 文件可以包含有關它所包含的文件的數據,如廠商和版本信息。
- 可移植性。處理 JAR 文件的機制是 Java 平臺核心 API 的標準部分。
jar
工具在默認情況下壓縮文件。未壓縮的 JAR 文件一般可以比壓縮過的 JAR 文件更快地裝載,因爲在裝載過程中要解壓縮文件,但是未壓縮的文件在網絡上的下載時間可能更長。
大多數 JAR 文件包含一個 META-INF 目錄,它用於存儲包和擴展的配置數據,如安全性和版本信息。Java 2 平臺識別並解釋 META-INF 目錄中的下述文件和目錄,以便配置應用程序、擴展和類裝載器:
- MANIFEST.MF。這個 manifest 文件定義了與擴展和包相關的數據。
- INDEX.LIST。 這個文件由
jar
工具的新選項-i
生成,它包含在應用程序或者擴展中定義的包的位置信息。它是 JarIndex 實現的一部分,並由類裝載器用於加速類裝載過程。 - xxx.SF。 這是 JAR 文件的簽名文件。佔位符 xxx標識了簽名者。
- xxx.DSA。 與簽名文件相關聯的簽名程序塊文件,它存儲了用於簽名 JAR 文件的公共簽名。
爲了用 JAR 文件執行基本的任務,要使用作爲Java Development Kit 的一部分提供的 Java Archive Tool ( jar
工具)。用 jar
命令調用 jar
工具。表 1 顯示了一些常見的應用:
功能 | 命令 |
用一個單獨的文件創建一個 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 文件中提取特定的文件 | jar xf jar-file archived-file... |
運行一個打包爲可執行 JAR 文件的應用程序 | java -jar app.jar |
二
一個 可執行的 jar 文件是一個自包含的 Java 應用程序,它存儲在特別配置的JAR 文件中,可以由 JVM 直接執行它而無需事先提取文件或者設置類路徑。要運行存儲在非可執行的 JAR 中的應用程序,必須將它加入到您的類路徑中,並用名字調用應用程序的主類。但是使用可執行的 JAR 文件,我們可以不用提取它或者知道主要入口點就可以運行一個應用程序。可執行 JAR 有助於方便發佈和執行 Java 應用程序。
創建一個可執行 JAR 很容易。首先將所有應用程序代碼放到一個目錄中。假設應用程序中的主類是 com.mycompany.myapp.Sample
。您要創建一個包含應用程序代碼的 JAR 文件並標識出主類。爲此,在某個位置(不是在應用程序目錄中)創建一個名爲 manifest
的文件,並在其中加入以下一行:
Main-Class: com.mycompany.myapp.Sample |
然後,像這樣創建 JAR 文件:
jar cmf manifest ExecutableJar.jar application-dir |
所要做的就是這些了 -- 現在可以用 java -jar
執行這個 JAR 文件 ExecutableJar.jar。
一個可執行的 JAR 必須通過 menifest 文件的頭引用它所需要的所有其他從屬 JAR。如果使用了 -jar
選項,那麼環境變量 CLASSPATH 和在命令行中指定的所有類路徑都被 JVM 所忽略。
既然我們已經將自己的應用程序打包到了一個名爲 ExecutableJar.jar 的可執行 JAR 中了,那麼我們就可以用下面的命令直接從文件啓動這個應用程序:
java -jar ExecutableJar.jar 三 密封 JAR 文件中的一個包意味着在這個包中定義的所有類都必須在同一個 JAR 文件中找到。這使包的作者可以增強打包類之間的版本一致性。密封還提供了防止代碼篡改的手段。 要密封包,需要在 JAR 的 manifest 文件中爲包添加一個
如果試圖從密封包所在的 JAR 文件以外的其他地方裝載密封包中的一個類,那麼 JVM 將拋出一個
假設 extension1.jar 和 extension2.jar 是同一個目錄中的兩個 JAR 文件,extension1.jar 的 manifest 文件包含以下頭:
這個頭表明 extension2.jar 中的類是 extension1.jar 中的類的 擴展類。extension1.jar 中的類可以調用 extension2.jar 中的類,並且不要求 extension2.jar 處在類路徑中。 在裝載使用擴展機制的 JAR 時,JVM 會高效而自動地將在 例如,假設類
在這個 manifest 中
四 JAR 文件可以用 JAR 文件是用一個存儲在 Keystore 數據庫中的證書籤名的。存儲在 keystore 中的證書有密碼保護,必須向
JAR 的每一位簽名者都由在 JAR 文件的 META-INF 目錄中的一個具有 .SF 擴展名的簽名文件表示。這個文件的格式類似於 manifest 文件 -- 一組 RFC-822 頭。如下所示,它的組成包括一個主要部分,它包括了由簽名者提供的信息、但是不特別針對任何特定的 JAR 文件項,還有一系列的單獨的項,這些項也必須包含在 menifest 文件中。在驗證一個簽名的 JAR 時,將簽名文件的摘要值與對 JAR 文件中的相應項計算的摘要值進行比較。
一個數字簽名是.SF 簽名文件的已簽名版本。數字簽名文件是二進制文件,並且與 .SF 文件有相同的文件名,但是擴展名不同。根據數字簽名的類型 -- RSA、DSA 或者 PGP -- 以及用於簽名 JAR 的證書類型而有不同的擴展名。 要簽名一個 JAR 文件,必須首先有一個私鑰。私鑰及其相關的公鑰證書存儲在名爲 所有 keystore 項(密鑰和信任的證書項)都是用唯一別名訪問的。別名是在用 例如,要用別名“james”生成一個新的公鑰/私鑰對並將公鑰包裝到自簽名的證書中,要使用下述命令:
這個命令序列指定了一個初始密碼“jamespass”,後續的命令在訪問 keystore
“jamesKeyStore”中與別名“james”相關聯的私鑰時,就需要這個密碼。如果 keystore“jamesKeyStore”不存在,則
假設像上述例子那樣創建了 keystore “jamesKeyStore”,並且它包含一個別名爲“james”的密鑰,可以用下面的命令簽名一個 JAR 文件:
這個命令用密碼“jamesKeyStorePass”從名爲“jamesKeyStore”的 keystore 中提出別名爲“james”、密碼爲“jamespass”的密鑰,並對 Sample.jar 文件簽名、創建一個簽名的 JAR -- SSample.jar。
如果簽名的 JAR 文件沒有被篡改過,那麼 還可以用
五 如果一個應用程序或者 applet 捆綁到多個 JAR 文件中,那麼類裝載器就使用一個簡單的線性搜索算法搜索類路徑中的每一個元素,這使類裝載器可能要下載並打開許多個 JAR 文件,直到找到所要的類或者資源。如果類裝載器試圖尋找一個不存在的資源,那麼在應用程序或者 applet 中的所有 JAR 文件都會下載。對於大型的網絡應用程序和 applet,這會導致啓動緩慢、響應遲緩並浪費帶寬。 從 JDK 1.3 以後,JAR 文件格式開始支持索引以優化網絡應用程序中類的搜索過程,特別是 applet。JarIndex 機制收集在 applet 或者應用程序中定義的所有 JAR 文件的內容,並將這些信息存儲到第一個 JAR 文件中的索引文件中。下載了第一個 JAR 文件後,applet 類裝載器將使用收集的內容信息高效地裝載 JAR 文件。這個目錄信息存儲在根 JAR 文件的 META-INF 目錄中的一個名爲 INDEX.LIST 的簡單文本文件中。 創建一個 JarIndex 您將使用下述命令爲 JarIndex_Main.jar、JarIndex_test.jar 和 JarIndex_test1.jar 創建一個索引文件:
INDEX.LIST 文件的格式很簡單,包含每個已索引的 JAR 文件中包含的包或者類的名字,如清單 2 所示:
|