探討JAR文件無限可能性--轉(zhuǎn)載
所有Java開發(fā)者都知道JAR文件只是包含Java類樹的壓縮(ZIP)文件。但是,不是人人(包括一些經(jīng)驗(yàn)豐富的開發(fā)者)了解這種文件格式的其它優(yōu)點(diǎn)。在本文中,我將簡單介紹JAR文件格式,并說明利用它可以實(shí)現(xiàn)的各種可能性。
JAR文件簡介
JAR文件以流行的二進(jìn)制ZIP文件格式為基礎(chǔ),用以把許多文件合并成一個(gè)文件。它還包含一個(gè)名為META-INF的可選目錄,這個(gè)目錄位于文件根目錄下。
有兩種方法可以建立JAR文件:應(yīng)用命令行工具jar,或使用Java中的java.util.jar API編程。如果JAR文件包含在Java類路徑中,使JVM可看到它,則JAR文件包含Java類和/或可由類加載器運(yùn)行、使用及加載的資源。
在許多情況下,JAR文件不僅僅是簡單的Java類檔案文件和/或資源;它們還可用來為應(yīng)用程序和擴(kuò)展建立語句塊。META-INF目錄(如存在)用于存儲(chǔ)數(shù)據(jù)包和擴(kuò)展配置數(shù)據(jù),包括安全、版本、擴(kuò)展和服務(wù)。
META-INF目錄的作用
META-INF目錄中的下列文件和目錄獲得Java 2平臺(tái)的認(rèn)可與解釋,用來配置應(yīng)用程序、擴(kuò)展程序、類加載器和服務(wù):
- MANIFEST.MF:清單文件,用來定義與擴(kuò)展和數(shù)據(jù)包相關(guān)的數(shù)據(jù)。
- INDEX.LIST:這個(gè)文件由JAR工具的新“-i”選項(xiàng)生成,其中包含在一個(gè)應(yīng)用程序或擴(kuò)展中定義的數(shù)據(jù)包的地址信息。它是JarIndex的一部分,被類加載器用來加速類加載過程。
- x.SF:JAR文件的簽名文件。x代表基礎(chǔ)文件名。
- x.DSA:這個(gè)簽名塊文件與同名基礎(chǔ)簽名文件有關(guān)。此文件存儲(chǔ)對(duì)應(yīng)簽名文件的數(shù)字簽名。
- services/:這個(gè)目錄存儲(chǔ)所有服務(wù)提供程序配置文件。
下面我們來了解一下每種組合。
清單文件
清單文件由“AttributeName: Value”對(duì)構(gòu)成,一個(gè)換行符將其劃分成兩個(gè)部分:主要部分和單獨(dú)部分,這兩個(gè)被另外一個(gè)換行符分開。
- 主要部分:這個(gè)部分包含JAR文件本身的安全和配置信息,以及此JAR文件構(gòu)成的應(yīng)用程序或擴(kuò)展。它還定義適用于每個(gè)單獨(dú)清單項(xiàng)的主要屬性。這個(gè)部分沒有名為“Name”的屬性。本部分以一個(gè)空行結(jié)束。
- 單獨(dú)部分:這個(gè)部分為此JAR文件中包含的數(shù)據(jù)包或文件定義各種屬性。并非所有的JAR文件都必須列舉在清單文件中,但必須列出所有簽名文件。清單文件本身不得列出。每個(gè)部分必須以一個(gè)名為“Name”的屬性開始,它的值必須是一個(gè)文件相對(duì)路徑,或檔案文件外的一個(gè)絕對(duì)URL參考數(shù)據(jù)。(我將在本文后部分討論JAR簽名。)
下面是清單文件最重要的屬性:
- Manifest-Version:定義清單文件版本。它的值是一個(gè)上面規(guī)范描述的合法版本號(hào)。
- Created-By:詳細(xì)說明生成這個(gè)清單文件的Java程序的版本和生產(chǎn)商。這個(gè)屬性由JAR工具生成。
- Signature-Version:定義JAR文件的簽名版本。該值應(yīng)為一個(gè)有效的版本號(hào)字符串。
- Class-Path:這個(gè)屬性值指定這個(gè)應(yīng)用程序或擴(kuò)展需要的擴(kuò)展或庫的相對(duì)URL。URL由一個(gè)或幾個(gè)空格分隔。應(yīng)用程序或擴(kuò)展類加載器使用這個(gè)屬性值建立它的內(nèi)部搜索路徑。
- Main-Class:這個(gè)屬性用于單機(jī)應(yīng)用程序。這個(gè)屬性值定義主要應(yīng)用程序類的相對(duì)路徑,發(fā)射器在啟動(dòng)時(shí)會(huì)加載這些類。這個(gè)屬性值不能在類名稱后附加.class擴(kuò)展名。如果你已經(jīng)指定這個(gè)屬性,JAR文件即變成可執(zhí)行文件,應(yīng)用程序?qū)⑼ㄟ^java –jar x.jar命令自動(dòng)啟動(dòng)。
- Sealed:這個(gè)屬性定義此JAR文件是否被密封。該值可為真或假,且忽略大小寫。當(dāng)JAR文件被密封時(shí),一個(gè)可選的數(shù)據(jù)包可在某個(gè)特殊的版本中執(zhí)行一貫性。在JAR中密封的數(shù)據(jù)包規(guī)定所有在那個(gè)數(shù)據(jù)包中定義的類必須源自相同的JAR;否則,就會(huì)產(chǎn)生一個(gè)SecurityException。例如,這段代碼:
Name: javax/servlet/internal/
Sealed: true
說明javax.servlet.internal數(shù)據(jù)包被密封,且這個(gè)數(shù)據(jù)包中的所有類必須從相同的JAR文件加載。要了解可選數(shù)據(jù)包的詳細(xì)內(nèi)容,請(qǐng)查看擴(kuò)展機(jī)制。
JAR簽名文件
任何JAR文件都可以通過java.security API,使用命令行jarsigner工具或目錄進(jìn)行簽名。通過文件簽名,你可以保證沒人能夠改變一個(gè)文件的內(nèi)容,以及你正在使用一個(gè)知名廠商的JAR文件。如果JAR文件用jarsigner工具簽名,那么每個(gè)文件,包括META-INF目錄中的相關(guān)非簽名文件,都將被簽名。下面是與簽名有關(guān)的文件:
- META-INF/MANIFEST.MF
- META-INF/*.SF
- META-INF/*.DSA
- META-INF/*.RSA
- META-INF/SIG-*
每個(gè)簽名器由一個(gè)擴(kuò)展名為.SF的簽名文件說明,這個(gè)文件的主要內(nèi)容與清單文件相似。它由一個(gè)主要部分構(gòu)成,其中包含由簽名器提供的信息,但并不特別針對(duì)某個(gè)特定的JAR文件。主要部分的項(xiàng)目x-Digest-Manifest-Main-Attributes(這里的x是一個(gè)摘要算法)包含清單主要屬性的摘要值。
要使一個(gè)文件生效,首先將簽名文件的一個(gè)摘要值與根據(jù)清單文件中對(duì)應(yīng)的項(xiàng)目計(jì)算的摘要進(jìn)行比較;然后,再將清單文件中的一個(gè)摘要值與根據(jù)“Name:”屬性中的實(shí)際引用數(shù)據(jù)計(jì)算的摘要比較。“Name:”屬性指定一個(gè)相對(duì)文件路徑或RUL。
例如,下面是一個(gè)簽名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)
下面是對(duì)應(yīng)的簽名:
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)
數(shù)字簽名是.SF簽名文件的一個(gè)簽名版本。這些是人類無法解譯的二進(jìn)制文件。數(shù)字簽名文件和.SF文件的名稱相同,但擴(kuò)展名不同。數(shù)字簽名的類型不同,其擴(kuò)展名也各不相同,通常為RSA或DSA。
JAR目錄
為優(yōu)化類加載器在網(wǎng)絡(luò)應(yīng)用程序,特別是applet中的類搜索過程,因此引入了JAR目錄(一般稱作JarIndex機(jī)制)。JarIndex機(jī)制收集在一個(gè)applet中定義的所有JAR文件,并將信息存儲(chǔ)在applet的類路徑的第一個(gè)JAR文件的一個(gè)目錄文件中。下載第一個(gè)JAR文件后,applet類加載器將收集內(nèi)容信息,這樣可提高JAR文件的下載效率。
系統(tǒng)對(duì)現(xiàn)有的JAR工具進(jìn)行強(qiáng)化,使其能夠檢查一個(gè)JAR文件列表,并生成目錄信息,說明哪些類和資源位于哪個(gè)JAR文件中。這些目錄信息存儲(chǔ)在根JAR文件META-INF目錄中的一個(gè)名為INDEX.LIST的簡單文本文件中。當(dāng)類加載器加載根JAR文件時(shí),它閱讀INDEX.LIST文件,并用它建立一個(gè)由文件和數(shù)據(jù)包名稱到JAR文件名列表的映射散列表。為了找到一個(gè)類或資源,類加載器查詢散列表找到正確的JAR文件,如有必要,再下載這個(gè)文件。
提供服務(wù)
META-INF/services目錄中的文件為服務(wù)提供程序配置文件。一個(gè)服務(wù)通常是一組著名的界面和(一般是抽象的)類。一個(gè)服務(wù)提供程序是一項(xiàng)服務(wù)的特殊執(zhí)行過程。提供程序中的類往往執(zhí)行上述界面并繼承服務(wù)本身定義的類。
服務(wù)提供程序通過把一個(gè)提供程序配置文件放在META-INF/services源目錄中來識(shí)別自己。這個(gè)文件名應(yīng)由完全合格的抽象服務(wù)類名稱構(gòu)成。
應(yīng)用這些特性
了解JAR文件的這些特性后,你就可以在實(shí)際開發(fā)工作中創(chuàng)造性的應(yīng)用它們。如果你已經(jīng)有了一些有趣的使用方法,請(qǐng)?jiān)谖恼碌挠懻摬糠址窒砟愕慕?jīng)驗(yàn)。
Peter V. Mikhalenko是一名通過Sun認(rèn)證的專家,現(xiàn)在任德意志銀行商業(yè)顧問。
責(zé)任編輯:德東
posted on 2008-03-07 10:36 心無痕 閱讀(495) 評(píng)論(0) 編輯 收藏 所屬分類: JAVA