www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 架構(gòu)師社區(qū)
[導(dǎo)讀]簡(jiǎn)介 java程序員每天不是在創(chuàng)建jar包就是在創(chuàng)建jar包的路上,并且各種依賴引用都是以jar包的形式展示的。但是隨著現(xiàn)代IDE的出現(xiàn),我想很多程序員已經(jīng)基本上很少直接和jar包打交道了。 換句話說(shuō),他們已經(jīng)不認(rèn)識(shí)jar包了。 那么jar包到底是什么呢?它有哪些小秘



簡(jiǎn)介



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


換句話說(shuō),他們已經(jīng)不認(rèn)識(shí)jar包了。


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



jar包到底是什么



jar包其實(shí)是一種zip格式的文件,所以說(shuō)你實(shí)際上是可以使用zip相關(guān)的命令來(lái)對(duì)jar包進(jìn)行創(chuàng)建或者解壓縮操作。


不同的是jar包中多了一個(gè)META-INF文件夾。


通過(guò)這個(gè)文件夾,jar包可以執(zhí)行更多的操作。


JDK也自帶了一個(gè)jar命令,通過(guò)jar命令我們可以實(shí)現(xiàn)創(chuàng)建,更新jar包的操作,下圖是JDK8中jar命令的說(shuō)明:

一文讀懂jar包的小秘密


因?yàn)镴DK9之后引入了模塊化的概念,所以JDK9之后jar命令有了比較大的變化:


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

一文讀懂jar包的小秘密


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



META-INF目錄



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

一文讀懂jar包的小秘密


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


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

Manifest-Version: 1.0Ant-Version: Apache Ant 1.7.1Created-By: 14.3-b01-101 (Apple Inc.)Premain-Class: lombok.launch.AgentAgent-Class: lombok.launch.AgentCan-Redefine-Classes: trueMain-Class: lombok.launch.MainLombok-Version: 1.18.10

MANIFEST.MF主要用來(lái)定義package相關(guān)的數(shù)據(jù),這里我們可以看到lombok的MANIFEST.MF文件定義了manifest的版本號(hào),創(chuàng)建時(shí)間,版本號(hào)和幾個(gè)類型的class。


services文件夾里面存放的可以對(duì)外提供的服務(wù)。


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

INDEX.LIST

可以使用 -i在生成jar包的時(shí)候自動(dòng)創(chuàng)建,是class的index文件,主要用來(lái)加速class加載。

x.SF

JAR包的簽名文件。

x.DSA

與具有相同基本文件名的簽名文件關(guān)聯(lián)的簽名塊文件。該文件存儲(chǔ)相應(yīng)簽名文件的數(shù)字簽名。

versions/

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


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


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


module-info.class



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


看一下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,同時(shí)也定義了對(duì)外提供的類。


在JDK9之后,存在兩種path,一種是之前的class path,一種是module path。當(dāng) modular JAR被部署在module path中的時(shí)候,它就是一個(gè)modular JAR。當(dāng)他被部署在class path中的時(shí)候,就是一個(gè)non-modular JAR。


同樣的,如果是一個(gè)non-modular JAR被定義在module path中,那么這個(gè)non-modular JAR就自動(dòng)被轉(zhuǎn)換成了一個(gè)automatic module。


如果jar包在MANIFEST.MF中定義了Automatic-Module-Name,那么module名字就是這個(gè)值,否則會(huì)從JAR的名字來(lái)定義這個(gè)module。


automatic module主要是為了向下兼容而產(chǎn)生的。


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



versions



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


Multi-Release: true

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


一般來(lái)說(shuō),目錄結(jié)構(gòu)是這樣的:META-INF/versions/N


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


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



MANIFEST.MF詳解



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


我們舉個(gè)簡(jiǎn)單的例子:

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

其中

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

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

一文讀懂jar包的小秘密


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


Name: foo/bar/Sealed: false

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


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



JAR包簽名



JAR包可以通過(guò)使用jarsigner來(lái)對(duì)其進(jìn)行簽名。和簽名相關(guān)的文件是:


META-INF/MANIFEST.MFMETA-INF/*.SFMETA-INF/*.DSAMETA-INF/*.RSAMETA-INF/SIG-*


簽名過(guò)后的jar跟原來(lái)的jar其實(shí)并沒(méi)有什么不同,只不過(guò)在META-INF/文件夾中多出了兩個(gè)文件,一個(gè)是簽名文件,一個(gè)是簽名block文件。

01

簽名文件

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


除此之外,還可以指定和安全相關(guān)的屬性:

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

  • x-Digest-Manifest:表示的是整個(gè)manifest的摘要。

這兩個(gè)屬性主要用來(lái)做驗(yàn)證簽名用的。


舉個(gè)例子:


如果我們的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)

那么相應(yīng)的簽名文件應(yīng)該是這樣的:

 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)

02

簽名文件的摘要

如果再對(duì).SF文件進(jìn)行摘要,那么就會(huì)得到簽名文件的摘要文件:

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




Sealed



上面我們講到了一個(gè)Sealed屬性:

Name: javax/servlet/internal/Sealed: true

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


這個(gè)屬性主要是從jar包的安全性來(lái)考慮的。

特別推薦一個(gè)分享架構(gòu)+算法的優(yōu)質(zhì)內(nèi)容,還沒(méi)關(guān)注的小伙伴,可以長(zhǎng)按關(guān)注一下:

一文讀懂jar包的小秘密

一文讀懂jar包的小秘密

一文讀懂jar包的小秘密

長(zhǎng)按訂閱更多精彩▼

一文讀懂jar包的小秘密

如有收獲,點(diǎn)個(gè)在看,誠(chéng)摯感謝


免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
關(guān)閉
關(guān)閉