日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

JAVA程序員每天不是在創建jar包就是在創建jar包的路上,并且各種依賴引用都是以jar包的形式展示的。但是隨著現代IDE的出現,我想很多程序員已經基本上很少直接和jar包打交道了。

換句話說,他們已經不認識jar包了。

那么jar包到底是什么呢?它有哪些小秘密呢?一起來看一下吧。

jar包到底是什么

jar包其實是一種zip格式的文件,所以說你實際上是可以使用zip相關的命令來對jar包進行創建或者解壓縮操作。

不同的是jar包中多了一個META-INF文件夾。通過這個文件夾,jar包可以執行更多的操作。

JDK也自帶了一個jar命令,通過jar命令我們可以實現創建,更新jar包的操作,下圖是JDK8中jar命令的說明:

一文讀懂jar包的小秘密

 

因為JDK9之后引入了模塊化的概念,所以JDK9之后jar命令有了比較大的變化:

我們看一下JDK14中的jar命令的用法:

一文讀懂jar包的小秘密

 

這里主要不是講jar命令,所以我們不具體展開。

META-INF目錄

jar包和zip包最大的區別就在于jar包中包含了META-INF目錄(不是必須的),我們看一個比較常用的lombok.jar包的結構是怎么樣的:

一文讀懂jar包的小秘密

 

這個版本比較新,所以它使用的是最新的JPMS的寫法,大家可以看到在jar包的根目錄下面有一個module-info.class文件,表示這個jar包使用的是模塊化。

然后再看一下META-INF目錄,里面有一個MANIFEST.MF文件:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.1
Created-By: 14.3-b01-101 (Apple Inc.)
Premain-Class: lombok.launch.Agent
Agent-Class: lombok.launch.Agent
Can-Redefine-Classes: true
Main-Class: lombok.launch.Main
Lombok-Version: 1.18.10

MANIFEST.MF主要用來定義package相關的數據,這里我們可以看到lombok的MANIFEST.MF文件定義了manifest的版本號,創建時間,版本號和幾個類型的class。

services文件夾里面存放的可以對外提供的服務。

這里列出的文件并不全,實際上還有下面幾種文件:

  • INDEX.LIST

可以使用 -i在生成jar包的時候自動創建,是class的index文件,主要用來加速class加載。

  • x.SF

JAR包的簽名文件。

  • x.DSA

與具有相同基本文件名的簽名文件關聯的簽名塊文件。 該文件存儲相應簽名文件的數字簽名。

  • versions/

主要為使用多版本的特性準備的,里面存儲的是不同版本的class和資源。

比如下面命令創建了多個版本發行的jar包,并且將一些文件放在 META-INF/versions/9 目錄中。

 jar --create --file mr.jar -C foo classes --release 9 -C foo9 classes

module-info.class

假如我們使用的是JDK9之后的JPMS模塊化,那么就會生成這么一個module-info.class。這個文件主要是描述模塊和外部模塊直接的關系。

看一下lombok的例子:

module lombok {
    requires java.compiler;
    requires java.instrument;
    requires jdk.unsupported;
    requires static org.mapstruct.processor;

    exports lombok;
    exports lombok.experimental;
    exports lombok.extern.apachecommons;
    exports lombok.extern.java;
    exports lombok.extern.jbosslog;
    exports lombok.extern.log4j;
    exports lombok.extern.slf4j;
    exports lombok.extern.flogger;

    provides javax.annotation.processing.Processor with lombok.launch.AnnotationProcessorHider$AnnotationProcessor;
    provides org.mapstruct.ap.spi.AstModifyingAnnotationProcessor with lombok.launch.AnnotationProcessorHider$AstModificationNotifier;
}

這里面我們定義了依賴的類和service providers,同時也定義了對外提供的類。

在JDK9之后,存在兩種path,一種是之前的class path,一種是module path。當 modular JAR被部署在module path中的時候,它就是一個modular JAR。當他被部署在class path中的時候,就是一個non-modular JAR。

同樣的,如果是一個non-modular JAR被定義在module path中,那么這個non-modular JAR就自動被轉換成了一個automatic module。

如果jar包在MANIFEST.MF中定義了Automatic-Module-Name,那么module名字就是這個值,否則會從JAR的名字來定義這個module。

automatic module主要是為了向下兼容而產生的。

關于JPMS的更多信息可以參考我之前寫的文章:JDK9的新特性:JPMS模塊化.

versions

versions主要和 multi-release JAR一起使用的:

Multi-Release: true

所謂multi-release JAR就是說一個jar包可以支持不同版本的JDK。我們可以根據需要指定不同版本的JDK所依賴的class文件或者屬性文件。這個特性在我們進行JDK升級的時候還是很有幫助的。

一般來說,目錄結構是這樣的:META-INF/versions/N

其中N表示的是JDK的主要發行版本,比如9,10,11等。

類加載器會先去META-INF/versions/N目錄中加載所需要的class,然后會去其他的低版本的META-INF/versions/N目錄中加載所需要的class,最后才會在META-INF/的根目錄加載其他的class文件。

MANIFEST.MF詳解

MANIFEST.MF中存放的是key:value格式的配置信息,這些配置信息又可以分成兩部分,第一部分是main-section信息,第二部分是individual-section。

我們舉個簡單的例子:

Manifest-Version: 1.0
Created-By: 1.8 (Oracle Inc.)
Sealed: true
Name: foo/bar/
Sealed: false

其中

Manifest-Version: 1.0
Created-By: 1.8 (Oracle Inc.)
Sealed: true

就是main-section信息,我們用一張圖來看一下main-section的信息有哪些:

一文讀懂jar包的小秘密

 

在main-section信息下發可以接一個Name: Value,表示開啟獨立的針對于具體entry的屬性(Per-Entry Attributes)配置:

Name: foo/bar/
Sealed: false

比如上面的屬性是專門針對于包foo/bar/的,并且設置其Sealed屬性為false。

Per-Entry Attributes除了 package versioning 和 sealing信息外,還可以定義Content-Type,Java-Bean,x-Digest-y和Magic屬性。

JAR包簽名

JAR包可以通過使用jarsigner來對其進行簽名。和簽名相關的文件是:

  • META-INF/MANIFEST.MF
  • META-INF/*.SF
  • META-INF/*.DSA
  • META-INF/*.RSA
  • META-INF/SIG-*

簽名過后的jar跟原來的jar其實并沒有什么不同,只不過在META-INF/文件夾中多出了兩個文件,一個是簽名文件,一個是簽名block文件。

簽名文件

簽名文件是以.SF結尾的,這個文件和MANIFEST.MF很類似,可以指定Signature-Version和Created-By。

除此之外,還可以指定和安全相關的屬性:

  • x-Digest-Manifest-Main-Attributes: 其中x是java.security.MessageDigest中指定的算法,表示的主要屬性的摘要。
  • x-Digest-Manifest: 表示的是整個manifest的摘要。

這兩個屬性主要用來做驗證簽名用的。

舉個例子:

如果我們的manifest是下面這樣的:

    Manifest-Version: 1.0
    Created-By: 1.8.0 (Oracle Inc.)

    Name: common/class1.class
    SHA-256-Digest: (base64 representation of SHA-256 digest)

    Name: common/class2.class
    SHA1-Digest: (base64 representation of SHA1 digest)
    SHA-256-Digest: (base64 representation of SHA-256 digest)

那么相應的簽名文件應該是這樣的:

    Signature-Version: 1.0
    SHA-256-Digest-Manifest: (base64 representation of SHA-256 digest)
    SHA-256-Digest-Manifest-Main-Attributes: (base64 representation of SHA-256 digest)

    Name: common/class1.class
    SHA-256-Digest: (base64 representation of SHA-256 digest)

    Name: common/class2.class
    SHA-256-Digest: (base64 representation of SHA-256 digest)

簽名文件的摘要

如果再對.SF文件進行摘要,那么就會得到簽名文件的摘要文件:

  • .RSA (PKCS7 signature, SHA-256 + RSA)
  • .DSA (PKCS7 signature, DSA)

Sealed

上面我們講到了一個Sealed屬性:

Name: javax/servlet/internal/
Sealed: true

這個屬性的意思是,javax/servlet/internal/包中的所有類必須從這個jar包中加載。

這個屬性主要是從jar包的安全性來考慮的。

本文已收錄于 http://www.flydean.com/java-jar-in-detail/

最通俗的解讀,最深刻的干貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!

歡迎關注我的公眾號:「程序那些事」,懂技術,更懂你!

分享到:
標簽:jar
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定