製作可執行的JAR文件包及jar命令詳解

常常在網上看到有人詢問:如何把java程序編譯成.exe文件。通常回答只有兩種,一種是製作一個可執行的JAR文件包,然後就可以像.chm文檔一樣雙擊運行了;而另一種是使用JET來進行
編譯。但是JET是要用錢買的,而且據說JET也不是能把所有的Java程序都編譯成執行文件,性能也要打些折扣。所以,使用製作可執行JAR文件包的方法就是最佳選擇了,何況它還能保持Java的跨平臺特性。

下面就來看看什麼是JAR文件包吧:

1.JAR文件包

JAR文件就是JavaArchiveFile,顧名思意,它的應用是與Java息息相關的,是Java的一種文檔格式。JAR文件非常類似ZIP文件——準確的說,它就是ZIP文件,所以叫它文件包。JAR文件與ZIP文件唯一的區別就是在JAR文件的內容中,包含了一個META-INF/MANIFEST.MF文件,這個文件是在生成JAR文件的時候自動創建的。舉個例子,如果我們具有如下目錄結構的一些文件:

  ==

  `--test

   `--Test.class

把它壓縮成ZIP文件test.zip,則這個ZIP文件的內部目錄結構爲:

  test.zip

  `--test

   `--Test.class

如果我們使用JDK的jar命令把它打成JAR文件包test.jar,則這個JAR文件的內部目錄結構爲:

  test.jar

  |--META-INF

  | `--MANIFEST.MF

  `--test

    `--Test.class

2.創建可執行的JAR文件包

製作一個可執行的JAR文件包來發布你的程序是JAR文件包最典型的用法。

Java程序是由若干個.class文件組成的。這些.class文件必須根據它們所屬的包不同而分級分目錄存放;運行前需要把所有用到的包的根目錄指定給CLASSPATH環境變量或者java命令的-cp參數;運行時還要到控制檯下去使用java命令來運行,如果需要直接雙擊運行必須寫Windows的批處理文件(.bat)或者Linux的Shell程序。因此,許多人說,Java是一種方便開發者苦了用戶的程序設計語言。

其實不然,如果開發者能夠製作一個可執行的JAR文件包交給用戶,那麼用戶使用起來就方便了。在Windows下安裝JRE(JavaRuntimeEnvironment)的時候,安裝文件會將.jar文件映射給javaw.exe打開。那麼,對於一個可執行的JAR文件包,用戶只需要雙擊它就可以運行程序了,和閱讀.chm文檔一樣方便(.chm文檔默認是由hh.exe打開的)。那麼,現在的關鍵,就是如何來創建這個可執行的JAR文件包。

創建可執行的JAR文件包,需要使用帶cvfm參數的jar命令,同樣以上述test目錄爲例,命令如下:

jarcvfmtest.jarmanifest.mftest

這裏test.jar和manifest.mf兩個文件,分別是對應的參數f和m,其重頭戲在manifest.mf。因爲要創建可執行的JAR文件包,光靠指定一個manifest.mf文件是不夠的,因爲MANIFEST是JAR文件包的特徵,可執行的JAR文件包和不可執行的JAR文件包都包含MANIFEST。關鍵在於可執行JAR文件包的MANIFEST,其內容包含了Main-Class一項。這在MANIFEST中書寫格式如下:

Main-Class:可執行主類全名(包含包名)

例如,假設上例中的Test.class是屬於test包的,而且是可執行的類(定義了publicstaticvoidmain(String[])方法),那麼這個manifest.mf可以編輯如下:

Main-Class:test.Test<回車>

這個manifest.mf可以放在任何位置,也可以是其它的文件名,只需要有Main-Class:test.Test一行,且該行以一個回車符結束即可。創建了manifest.mf文件之後,我們的目錄結構變爲:

  ==

  |--test

  | `--Test.class

  `--manifest.mf

這時候,需要到test目錄的上級目錄中去使用jar命令來創建JAR文件包。也就是在目錄樹中使用“==”表示的那個目錄中,使用如下命令:

jarcvfmtest.jarmanifest.mftest

之後在“==”目錄中創建了test.jar,這個test.jar就是執行的JAR文件包。運行時只需要使用java-jartest.jar命令即可。

需要注意的是,創建的JAR文件包中需要包含完整的、與Java程序的包結構對應的目錄結構,就像上例一樣。而Main-Class指定的類,也必須是完整的、包含包路徑的類名,如上例的test.Test;而且在沒有打成JAR文件包之前可以使用java<類名>來運行這個類,即在上例中javatest.Test是可以正確運行的(當然要在CLASSPATH正確的情況下)。

3.jar命令詳解

jar是隨JDK安裝的,在JDK安裝目錄下的bin目錄中,Windows下文件名爲jar.exe,Linux下文件名爲jar。它的運行需要用到JDK安裝目錄下lib目錄中的tools.jar文件。不過我們除了安裝JDK什麼也不需要做,因爲SUN已經幫我們做好了。我們甚至不需要將tools.jar放到CLASSPATH中。

使用不帶任何的jar命令我們可以看到jar命令的用法如下:

jar{ctxu}[vfm0M][jar-文件][manifest-文件][-C目錄]文件名...

其中{ctxu}是jar命令的子命令,每次jar命令只能包含ctxu中的一個,它們分別表示:

-c 創建新的JAR文件包

-t 列出JAR文件包的內容列表

-x 展開JAR文件包的指定文件或者所有文件

-u 更新已存在的JAR文件包(添加文件到JAR文件包中)

[vfm0M]中的選項可以任選,也可以不選,它們是jar命令的選項參數

-v 生成詳細報告並打印到標準輸出

-f 指定JAR文件名,通常這個參數是必須的

-m 指定需要包含的MANIFEST清單文件

-0 只存儲,不壓縮,這樣產生的JAR文件包會比不用該參數產生的體積大,但速度更快

-M 不產生所有項的清單(MANIFEST〕文件,此參數會忽略-m參數

[jar-文件]即需要生成、查看、更新或者解開的JAR文件包,它是-f參數的附屬參數

[manifest-文件]即MANIFEST清單文件,它是-m參數的附屬參數

[-C目錄]表示轉到指定目錄下去執行這個jar命令的操作。它相當於先使用cd命令轉該目錄下再執行不帶-C參數的jar命令,它只能在創建和更新JAR文件包的時候可用。  

文件名...指定一個文件/目錄列表,這些文件/目錄就是要添加到JAR文件包中的文件/目錄。如果指定了目錄,那麼jar命令打包的時候會自動把該目錄中的所有文件和子目錄打入包中。

下面舉一些例子來說明jar命令的用法:

1)jarcftest.jartest

該命令沒有執行過程的顯示,執行結果是在當前目錄生成了test.jar文件。如果當前目錄已經存在test.jar,那麼該文件將被覆蓋。

2)jarcvftest.jartest

該命令與上例中的結果相同,但是由於v參數的作用,顯示出了打包過程,如下:

標明清單(manifest)

增加:test/(讀入=0)(寫出=0)(存儲了0%)

增加:test/Test.class(讀入=7)(寫出=6)(壓縮了14%)

3)jarcvfMtest.jartest

該命令與2)結果類似,但在生成的test.jar中沒有包含META-INF/MANIFEST文件,打包過程的信息也略有差別:

增加:test/(讀入=0)(寫出=0)(存儲了0%)

增加:test/Test.class(讀入=7)(寫出=6)(壓縮了14%)

4)jarcvfmtest.jarmanifest.mftest

運行結果與2)相似,顯示信息也相同,只是生成JAR包中的META-INF/MANIFEST內容不同,是包含了manifest.mf的內容

5)jartftest.jar

在test.jar已經存在的情況下,可以查看test.jar中的內容,如對於2)和3)生成的test.jar分別應該此命令,結果如下;

對於2)

META-INF/

META-INF/MANIFEST.MF

test/

test/Test.class

對於3)

test/

test/Test.class

6)jartvftest.jar

除顯示5)中顯示的內容外,還包括包內文件的詳細信息,如:

0WedJun1915:39:06GMT2002META-INF/

86WedJun1915:39:06GMT2002META-INF/MANIFEST.MF

0WedJun1915:33:04GMT2002test/

7WedJun1915:33:04GMT2002test/Test.class

7)jarxftest.jar

解開test.jar到當前目錄,不顯示任何信息,對於2)生成的test.jar,解開後的目錄結構如下:

  ==

  |--META-INF

  | `--MANIFEST

  `--test

    `--Test.class

8)jarxvftest.jar

運行結果與7)相同,對於解壓過程有詳細信息顯示,如:

創建:META-INF/

展開:META-INF/MANIFEST.MF

創建:test/

展開:test/Test.class

9)jaruftest.jarmanifest.mf

在test.jar中添加了文件manifest.mf,此使用jartf來查看test.jar可以發現test.jar中比原來多了一個manifest。這裏順便提一下,如果使用-m參數並指定manifest.mf文件,那麼manifest.mf是作爲清單文件MANIFEST來使用的,它的內容會被添加到MANIFEST中;但是,如果作爲一般文件添加到JAR文件包中,它跟一般文件無異。

10)jaruvftest.jarmanifest.mf

與9)結果相同,同時有詳細信息顯示,如:

增加:manifest.mf(讀入=17)(寫出=19)(壓縮了-11%)

4.關於JAR文件包的一些技巧

1)使用unzip來解壓JAR文件

在介紹JAR文件的時候就已經說過了,JAR文件實際上就是ZIP文件,所以可以使用常見的一些解壓ZIP文件的工具來解壓JAR文件,如Windows下的WinZip、WinRAR等和Linux下的unzip等。使用WinZip和WinRAR等來解壓是因爲它們解壓比較直觀,方便。而使用unzip,則是因爲它解壓時可以使用-d參數指定目標目錄。

在解壓一個JAR文件的時候是不能使用jar的-C參數來指定解壓的目標的,因爲-C參數只在創建或者更新包的時候可用。那麼需要將文件解壓到某個指定目錄下的時候就需要先將這具JAR文件拷貝到目標目錄下,再進行解壓,比較麻煩。如果使用unzip,就不需要這麼麻煩了,只需要指定一個-d參數即可。如:

unziptest.jar-ddest/

2)使用WinZip或者WinRAR等工具創建JAR文件

上面提到JAR文件就是包含了META-INF/MANIFEST的ZIP文件,所以,只需要使用WinZip、WinRAR等工具創建所需要ZIP壓縮包,再往這個ZIP壓縮包中添加一個包含MANIFEST文件的META-INF目錄即可。對於使用jar命令的-m參數指定清單文件的情況,只需要將這個MANIFEST按需要修改即可。

3)使用jar命令創建ZIP文件

有些Linux下提供了unzip命令,但沒有zip命令,所以需要可以對ZIP文件進行解壓,即不能創建ZIP文件。如要創建一個ZIP文件,使用帶-M參數的jar命令即可,因爲-M參數表示製作JAR包的時候不添加MANIFEST清單,那麼只需要在指定目標JAR文件的地方將.jar擴展名改爲.zip擴展名,創建的就是一個不折不扣的ZIP文件了,如將上一節的第3)個例子略作改動:
發佈了14 篇原創文章 · 獲贊 0 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章