JAR文件簡介
JAR文件以流行的二進制ZIP文件格式為基礎,用以把許多文件合并成一個文件。它還包含一個名為META-INF的可選目錄,這個目錄位于文件根目錄下。
有兩種方法可以建立JAR文件:應用命令行工具jar,或使用Java中的java.util.jar API編程。如果JAR文件包含在Java類路徑中,使JVM可看到它,則JAR文件包含Java類和/或可由類加載器運行、使用及加載的資源。
在許多情況下,JAR文件不僅僅是簡單的Java類檔案文件和/或資源;它們還可用來為應用程序和擴展建立語句塊。META-INF目錄(如存在)用于存儲數據包和擴展配置數據,包括安全、版本、擴展和服務。
META-INF目錄的作用
META-INF目錄中的下列文件和目錄獲得Java 2平臺的認可與解釋,用來配置應用程序、擴展程序、類加載器和服務:
MANIFEST.MF:清單文件,用來定義與擴展和數據包相關的數據。
INDEX.LIST:這個文件由JAR工具的新“-i”選項生成,其中包含在一個應用程序或擴展中定義的數據包的地址信息。它是JarIndex的一部分,被類加載器用來加速類加載過程。
x.SF:JAR文件的簽名文件。x代表基礎文件名。
x.DSA:這個簽名塊文件與同名基礎簽名文件有關。此文件存儲對應簽名文件的數字簽名。
services/:這個目錄存儲所有服務提供程序配置文件。
下面我們來了解一下每種組合。
清單文件
清單文件由“AttributeName: Value”對構成,一個換行符將其劃分成兩個部分:主要部分和單獨部分,這兩個被另外一個換行符分開。
主要部分:這個部分包含JAR文件本身的安全和配置信息,以及此JAR文件構成的應用程序或擴展。它還定義適用于每個單獨清單項的主要屬性。這個部分沒有名為“Name”的屬性。本部分以一個空行結束。
單獨部分:這個部分為此JAR文件中包含的數據包或文件定義各種屬性。并非所有的JAR文件都必須列舉在清單文件中,但必須列出所有簽名文件。清單文件本身不得列出。每個部分必須以一個名為“Name”的屬性開始,它的值必須是一個文件相對路徑,或檔案文件外的一個絕對URL參考數據。(我將在本文后部分討論JAR簽名。)
下面是清單文件最重要的屬性:
Manifest-Version:定義清單文件版本。它的值是一個上面規范描述的合法版本號。
Created-By:詳細說明生成這個清單文件的Java程序的版本和生產商。這個屬性由JAR工具生成。
Signature-Version:定義JAR文件的簽名版本。該值應為一個有效的版本號字符串。
Class-Path:這個屬性值指定這個應用程序或擴展需要的擴展或庫的相對URL。URL由一個或幾個空格分隔。應用程序或擴展類加載器使用這個屬性值建立它的內部搜索路徑。
Main-Class:這個屬性用于單機應用程序。這個屬性值定義主要應用程序類的相對路徑,發射器在啟動時會加載這些類。這個屬性值不能在類名稱后附加.class擴展名。如果你已經指定這個屬性,JAR文件即變成可執行文件,應用程序將通過java –jar x.jar命令自動啟動。
Sealed:這個屬性定義此JAR文件是否被密封。該值可為真或假,且忽略大小寫。當JAR文件被密封時,一個可選的數據包可在某個特殊的版本中執行一貫性。在JAR中密封的數據包規定所有在那個數據包中定義的類必須源自相同的JAR;否則,就會產生一個SecurityException。例如,這段代碼:
Name: javax/servlet/internal/
Sealed: true
說明javax.servlet.internal數據包被密封,且這個數據包中的所有類必須從相同的JAR文件加載。要了解可選數據包的詳細內容,請查看擴展機制。
JAR簽名文件
任何JAR文件都可以通過java.security API,使用命令行jarsigner工具或目錄進行簽名。通過文件簽名,你可以保證沒人能夠改變一個文件的內容,以及你正在使用一個知名廠商的JAR文件。如果JAR文件用jarsigner工具簽名,那么每個文件,包括META-INF目錄中的相關非簽名文件,都將被簽名。下面是與簽名有關的文件:
META-INF/MANIFEST.MF
META-INF/*.SF
META-INF/*.DSA
META-INF/*.RSA
META-INF/SIG-*
每個簽名器由一個擴展名為.SF的簽名文件說明,這個文件的主要內容與清單文件相似。它由一個主要部分構成,其中包含由簽名器提供的信息,但并不特別針對某個特定的JAR文件。主要部分的項目x-Digest-Manifest-Main-Attributes(這里的x是一個摘要算法)包含清單主要屬性的摘要值。
要使一個文件生效,首先將簽名文件的一個摘要值與根據清單文件中對應的項目計算的摘要進行比較;然后,再將清單文件中的一個摘要值與根據“Name:”屬性中的實際引用數據計算的摘要比較?!癗ame:”屬性指定一個相對文件路徑或RUL。
例如,下面是一個簽名JAR的清單文件:
Manifest-Version: 1.0
Created-By: 1.3 (Sun Microsystems, Inc)?br>
Name: common/class1.class
MD5-Digest: (base64 representation of MD5 digest)?br>
Name: common/class2.class
MD5-Digest: (base64 representation of MD5 digest)
SHA-Digest: (base64 representation of SHA digest)
下面是對應的簽名:
Signature-Version: 1.0
MD5-Digest-Manifest-Main-Attributes: (base64 representation of MD5 digest)?br>
Name: common/class1.class
MD5-Digest: (base64 representation of MD5 digest)?br>
Name: common/class2.class
MD5-Digest: (base64 representation of MD5 digest)
數字簽名是.SF簽名文件的一個簽名版本。這些是人類無法解譯的二進制文件。數字簽名文件和.SF文件的名稱相同,但擴展名不同。數字簽名的類型不同,其擴展名也各不相同,通常為RSA或DSA。
JAR目錄
為優化類加載器在網絡應用程序,特別是applet中的類搜索過程,因此引入了JAR目錄(一般稱作JarIndex機制)。JarIndex機制收集在一個applet中定義的所有JAR文件,并將信息存儲在applet的類路徑的第一個JAR文件的一個目錄文件中。下載第一個JAR文件后,applet類加載器將收集內容信息,這樣可提高JAR文件的下載效率。
系統對現有的JAR工具進行強化,使其能夠檢查一個JAR文件列表,并生成目錄信息,說明哪些類和資源位于哪個JAR文件中。這些目錄信息存儲在根JAR文件META-INF目錄中的一個名為INDEX.LIST的簡單文本文件中。當類加載器加載根JAR文件時,它閱讀INDEX.LIST文件,并用它建立一個由文件和數據包名稱到JAR文件名列表的映射散列表。為了找到一個類或資源,類加載器查詢散列表找到正確的JAR文件,如有必要,再下載這個文件。
提供服務
META-INF/services目錄中的文件為服務提供程序配置文件。一個服務通常是一組著名的界面和(一般是抽象的)類。一個服務提供程序是一項服務的特殊執行過程。提供程序中的類往往執行上述界面并繼承服務本身定義的類。
服務提供程序通過把一個提供程序配置文件放在META-INF/services源目錄中來識別自己。這個文件名應由完全合格的抽象服務類名稱構成。
應用這些特性
了解JAR文件的這些特性后,你就可以在實際開發工作中創造性的應用它們。如果你已經有了一些有趣的使用方法,請在文章的討論部分分享你的經驗
(責任編輯:龔勛)
原文轉自:http://www.anti-gravitydesign.com