jar包解讀

一、什么是jar包

jar包就是 Java Archive File,顧名思義,它的應用是與 Java 息息相關的,是 Java 的一種文檔格式,是一種與平臺無關的文件格式,可將多個文件合成一個文件。jar 包與 zip 包非常相似——準確地說,它就是 zip 包,所以叫它文件包。jar 與 zip 唯一的區(qū)別就是在 jar 文件的內(nèi)容中,包含了一個 META-INF/MANIFEST.MF 文件,該文件是在生成 jar 文件的時候自動創(chuàng)建的,作為jar里面的"詳情單",包含了該Jar包的版本、創(chuàng)建人和類搜索路徑Class-Path等信息,當然如果是可執(zhí)行Jar包,會包含Main-Class屬性,表明Main方法入口,尤其是較為重要的Class-Path和Main-Class。

此外,值得注意的是,因為jar包主要是對class文件進行打包,而java編譯生成的class文件是平臺無關的,這就意味著jar包是跨平臺的,所以不必關心涉及具體平臺的問題。說到jar里面的文件,咱們來看看最普通的一個帶有靜態(tài)頁面的springboot項目jar里面的內(nèi)容,就會發(fā)現(xiàn)解壓出來的jar并不簡單,為了貼近實際咱們未做任何刪減,可以看到有很多東西

只需要運行如下指令,就能看到jar里面的內(nèi)容(調(diào)用jar指令的前提是已經(jīng)配置了jdk的環(huán)境變量)

jar -tf springbootdemo-0.0.1-SNAPSHOT.jar

其中-tf 后接的jar就是我們要查看的jar。

大致看看里面的東西我們可以發(fā)現(xiàn),除了.MF以及.class文件之外,jar還能打包靜態(tài)資源文件如.html、.css以及.js等項目所需的一切,這也就意味著咱們能將自己的項目打成jar,即不管是web應用還是底層框架,都能打成jar包。

有的jar包是可以直接通過 java -jar 指令來執(zhí)行的。我們都知道,有的類之所以能夠執(zhí)行,是因為它用你有main函數(shù),該函數(shù)是程序的入口,同理,可執(zhí)行的jar包中肯定是有某個.class文件提供了main函數(shù)才使得其可執(zhí)行。那么問題來了,一個jar里面可能存在多個.class文件都有main函數(shù)的情況,我怎么知道該執(zhí)行哪個?其實答案非常簡單,就是看前面說的MANIFEST.MF里面的Main-Class屬性,它會指定函數(shù)入口。

二、為什么要打jar包

當我們開發(fā)了一個程序以后,程序中有很多的類,如果需要提供給別人使用,發(fā)給對方一大堆源文件是非常不好的,因此通常需要把這些類以及相關的資源文件打包成一個 jar 包,把這個 jar 包提供給別人使用,同時提供給使用者清晰的文檔。這樣他人在拿到我們提供的jar之后,就能方便地進行調(diào)用。而且安全。能夠?qū)AR文件進行數(shù)字簽名,只讓能夠識別數(shù)字簽名的用戶使用里面的東西。

因此,建議大家在平時寫代碼搬磚的時候,注意把自己代碼的通用部分抽離出來,主鍵積累一些通用的util類,將其逐漸模塊化,最后打成jar包供自己在別的項目或者模塊中使用,同時不斷打磨jar里面的內(nèi)容,將其做得越來越容易理解和通用,這樣的好處是除了會對你的代碼重構(gòu)能力以及模塊抽象能力有很好的幫助之外,更是一種從長期解放你的重復工作量,讓你有更多的精力去做其他事情的方式,甚至當你抽象出業(yè)內(nèi)足夠通用的jar之后,jar包還能為你帶來意想不到的利潤(當然公司里該保密的東西還是得保密的)。這也是java發(fā)展得如此之好的原因,無論出于盈利或者非盈利的目的,將自己的通用工具或者框架抽取出來,打成jar包供他人調(diào)用,使得整個java生態(tài)圈變得越來越強大–幾乎很多業(yè)務場景都能找到對應的jar包。

三、如何打jar包

1、通過jdk命令

A:含有多個類的jar,類之間存在調(diào)用關系

先創(chuàng)建一個java項目,編寫兩個非常簡單的類,Welcome.java和Teacher.jar,其中Welcome類在main函數(shù)里調(diào)用了Teacher類的靜態(tài)方法greeting

Welcome.java

packagecom.imooc.jardemo1;

importcom.imooc.jardemo1.impl.Teacher;

publicclassWelcome{

publicstaticvoidmain(String[] args){

? ? ? ? Teacher.greeting();

? ? }

}

Teacher.java

packagecom.imooc.jardemo1.impl;

publicclassTeacher{

publicstaticvoidgreeting(){

System.out.printf("Welcome!");

? ? }

}

在命令行里,去到項目的src路徑下,執(zhí)行javac指令

javac com/imooc/jardemo1/Welcome.java

此時就會生成與這兩個類相對應的.class字節(jié)碼文件

由于jvm實際解析的是.class字節(jié)碼文件而非.java文件,且jar中最好不要包含代碼源文件,我們來將.class文件打個jar包,在src根目錄下執(zhí)行如下指令

jar -cvf welcome.jar com/imooc/jardemo1/Welcome.class com/imooc/jardemo1/impl/Teacher.class

c表示要創(chuàng)建一個新的jar包,v表示創(chuàng)建的過程中在控制臺輸出創(chuàng)建過程的一些信息,f表示給生成的jar包命名

打jar的時候,會生成一個META-INF的目錄,里面有MANIFEST.MF這個清單列表。內(nèi)容為:

Manifest-Version: 1.0 Created-By: 11 (Oracle Corporation)

此時生成的jar包還不能執(zhí)行,因為缺少咱們先前說的Main-Class屬性,導致jar被執(zhí)行的時候,不知道執(zhí)行哪個main函數(shù)。因此我們需要加上Main-Class,后接main函數(shù)所在類的全路徑名(注意冒號之后一定要跟英文的空格,整個文件最后有一行空行)。

Manifest-Version: 1.0 Created-By: 11 (Oracle Corporation) Main-Class:

com.imooc.jardemo1.Welcome

添加完成后,重新執(zhí)行指令打包,這次咱們在打包指令里多加一個參數(shù),即多傳入修改完成后的MANIFEST.MF文件

jar -cvfm welcome.jar META-INF/MANIFEST.MF com/imooc/jardemo1/Welcome.class com/imooc/jardemo1/impl/Teacher.class

其中多了一個參數(shù)m,表示要定義MANIFEST文件。之后再重新執(zhí)行

java -jar welcome.jar

就會發(fā)現(xiàn)jar已成功執(zhí)行

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容