得益於Ant、Maven等構建工具的強大功能,我們無需每天冗繁的手動通過jar
命令來打包Java class和資源檔,軟體的日常打包部署通常都交給它們處理了。不過最近遇到點構建的問題,查了JAR相關的一些文章。在此做一個總結,對JAR有興趣的朋友可以一看。
什麼是JAR
JAR全稱為Java Archive,zip格式的Java打包檔案。目的是用來把class檔案,資源檔打包成一個檔案,利於部署,發布,以及傳輸。除了打包功能,它被用來構建應用組件(Application Blocks),構建Java擴充(Extension)。此外還包含一個可選的META-INFO目錄,可以用來儲存版本(Version),安全(Security, signer),索引(Index),服務(Services)等資訊。JAR可以通過的jar命令或者java.util.jar API產生。
JAR的常用命令
- 打包一個或者多個檔案
jar cvf example.jar class1.class class2.class
- 打包檔案夾
jar cvf example.jar -C build/ .
- 查看JAR的目錄(內容)
jar tf example.jar
- 解壓JAR檔案
jar xf example.jar
- 運行可執行檔JAR檔案
jar -jar example.jar
- 為JAR檔案添加索引
jar i exaple.jar
- 指定MANIFEST.MF打包
jar cvfm example.jar MyMANIFEST.MF -C build/ .
可選META-INFO檔案夾的格式說明
JAR包含一個可選的META-INF,不過JAR與ZIP的區別正在於此。所有的配置資訊都存於該目錄。主要包括以下一些檔案以及檔案夾:
- MANIFEST.MF
最重要的的設定檔,儲存版本,建立者,包等資訊。
- INDEX.LIST
JAR的索引資訊,加快JVM搜尋和載入class的速度,可選,通過i
可選項產生。
- key.SF和key.DSA
key.SF為簽名檔案,key.DSA為key.SF對應的加密資料塊(位元據,以base64編碼儲存),key為keytool產生的key的名稱。
- services檔案夾
儲存Service Provider的配置資訊
瞭解MANIFEST.MF
由一個主區以及不限數目的個人化區(Section)組成。個人化區可以覆蓋主區的值。所有的配置資訊都是鍵值對(Key:Value),區之間用空行隔開。
主區(Main Section)屬性:
- Manifest-Version
版本號碼,如1.0.0
- Create-By
建立者,如 1.6.0_35 (Sun Microsystems Inc.)
- Class-Path
JVM搜尋class的路徑,值得強調的是預設為相對路徑,並且環境變數以及命令列參數傳入的class-path無效了,被覆蓋(Override)了。多個 lib之間用空格隔開。如lib/slf4j-api-1.6.4.jar lib/log4j-1.2.16.jar
- Main-Class
可執行JAR包的入口類名,含包名。如 com.example.Start
個人化區(Individual Section)屬性:
個人化地區都以Name:開始,標記配置的時哪一個檔案或者檔案夾。比如: Name: com.example.Start
。除了主區的屬性外還包括:
- Sealed
Sealed: true
表示所有package內的class都需要在當前JAR包找到。
- Content-Type
檔案類型,格式為type/subtype,如image/bmp
- Java-Bean
標識某個class是否是Java Bean,值為true或者false。
簽名的JAR檔案
通過給JAR檔案簽名,可以驗證JAR檔案是否被篡改過。一個被簽名的JAR與簽名之前相比,MANIFEST.MF檔案會新增一些記錄,另外還會新增兩個檔案,加密資訊清單檔key.SF和加密資料塊檔案key.DSA。加密的步驟如下:
參考連結
- Java Guide
- JAR files revealed