怎樣制作可執(zhí)行的java程序
2024-07-21 02:39:02
供稿:網(wǎng)友
經(jīng)常在網(wǎng)上看到有人詢問(wèn):如何把java程序編譯成.exe文件。通常回答只有兩種,一種是制作一個(gè)可執(zhí)行的JAR文件包,然后就可以像.chm文檔一樣雙擊運(yùn)行了;而另一種是使用JET來(lái)進(jìn)行
編譯。但是JET是要用錢(qián)買(mǎi)的,而且據(jù)說(shuō)JET也不是能把所有的Java程序都編譯成執(zhí)行文件,性能也要打些折扣。所以,使用制作可執(zhí)行JAR文件包的方法就是最佳選擇了,何況它還能保持Java的跨平臺(tái)特性。
下面就來(lái)看看什么是JAR文件包吧:
1.JAR文件包
JAR文件就是JavaArchiveFile,顧名思意,它的應(yīng)用是與Java息息相關(guān)的,是Java的一種文檔格式。JAR文件非常類似Zip文件--準(zhǔn)確的說(shuō),它就是ZIP文件,所以叫它文件包。JAR文件與ZIP文件唯一的區(qū)別就是在JAR文件的內(nèi)容中,包含了一個(gè)META-INF/MANIFEST.MF文件,這個(gè)文件是在生成JAR文件的時(shí)候自動(dòng)創(chuàng)建的。舉個(gè)例子,假如我們具有如下目錄結(jié)構(gòu)的一些文件:
==
`--test
`--Test.class
把它壓縮成ZIP文件test.zip,則這個(gè)ZIP文件的內(nèi)部目錄結(jié)構(gòu)為:
test.zip
`--test
`--Test.class
假如我們使用JDK的jar命令把它打成JAR文件包test.jar,則這個(gè)JAR文件的內(nèi)部目錄結(jié)構(gòu)為:
test.jar
--META-INF
`--MANIFEST.MF
`--test
`--Test.class
2.創(chuàng)建可執(zhí)行的JAR文件包
制作一個(gè)可執(zhí)行的JAR文件包來(lái)發(fā)布你的程序是JAR文件包最典型的用法。
Java程序是由若干個(gè).class文件組成的。這些.class文件必須根據(jù)它們所屬的包不同而分級(jí)分目錄存放;運(yùn)行前需要把所有用到的包的根目錄指定給CLASSPATH環(huán)境變量或者java命令的-cp參數(shù);運(yùn)行時(shí)還要到控制臺(tái)下去使用java命令來(lái)運(yùn)行,假如需要直接雙擊運(yùn)行必須寫(xiě)Windows的批處理文件(.bat)或者linux的Shell程序。因此,許多人說(shuō),Java是一種方便開(kāi)發(fā)者苦了用戶的程序設(shè)計(jì)語(yǔ)言。
其實(shí)不然,假如開(kāi)發(fā)者能夠制作一個(gè)可執(zhí)行的JAR文件包交給用戶,那么用戶使用起來(lái)就方便了。在Windows下安裝JRE(JavaRuntimeEnvironment)的時(shí)候,安裝文件會(huì)將.jar文件映射給javaw.exe打開(kāi)。那么,對(duì)于一個(gè)可執(zhí)行的JAR文件包,用戶只需要雙擊它就可以運(yùn)行程序了,和閱讀.chm文檔一樣方便(.chm文檔默認(rèn)是由hh.exe打開(kāi)的)。那么,現(xiàn)在的要害,就是如何來(lái)創(chuàng)建這個(gè)可執(zhí)行的JAR文件包。
創(chuàng)建可執(zhí)行的JAR文件包,需要使用帶cvfm參數(shù)的jar命令,同樣以上述test目錄為例,命令如下:
jarcvfmtest.jarmanifest.mftest
這里test.jar和manifest.mf兩個(gè)文件,分別是對(duì)應(yīng)的參數(shù)f和m,其重頭戲在manifest.mf。因?yàn)橐獎(jiǎng)?chuàng)建可執(zhí)行的JAR文件包,光靠指定一個(gè)manifest.mf文件是不夠的,因?yàn)镸ANIFEST是JAR文件包的特征,可執(zhí)行的JAR文件包和不可執(zhí)行的JAR文件包都包含MANIFEST。要害在于可執(zhí)行JAR文件包的MANIFEST,其內(nèi)容包含了Main-Class一項(xiàng)。這在MANIFEST中書(shū)寫(xiě)格式如下:
Main-Class:可執(zhí)行主類全名(包含包名)
例如,假設(shè)上例中的Test.class是屬于test包的,而且是可執(zhí)行的類(定義了publicstaticvoidmain(String[])方法),那么這個(gè)manifest.mf可以編輯如下:
Main-Class:test.Test<回車>
這個(gè)manifest.mf可以放在任何位置,也可以是其它的文件名,只需要有Main-Class:test.Test一行,且該行以一個(gè)回車符結(jié)束即可。創(chuàng)建了manifest.mf文件之后,我們的目錄結(jié)構(gòu)變?yōu)椋?br />
==
test
Test.class
manifest.mf
這時(shí)候,需要到test目錄的上級(jí)目錄中去使用jar命令來(lái)創(chuàng)建JAR文件包。也就是在目錄樹(shù)中使用“==”表示的那個(gè)目錄中,使用如下命令:
jarcvfmtest.jarmanifest.mftest
之后在“==”目錄中創(chuàng)建了test.jar,這個(gè)test.jar就是執(zhí)行的JAR文件包。運(yùn)行時(shí)只需要使用java-jartest.jar命令即可。
需要注重的是,創(chuàng)建的JAR文件包中需要包含完整的、與Java程序的包結(jié)構(gòu)對(duì)應(yīng)的目錄結(jié)構(gòu),就像上例一樣。而Main-Class指定的類,也必須是完整的、包含包路徑的類名,如上例的test.Test;而且在沒(méi)有打成JAR文件包之前可以使用java<類名>來(lái)運(yùn)行這個(gè)類,即在上例中javatest.Test是可以正確運(yùn)行的(當(dāng)然要在CLASSPATH正確的情況下)。
3.jar命令詳解
jar是隨JDK安裝的,在JDK安裝目錄下的bin目錄中,Windows下文件名為jar.exe,Linux下文件名為jar。
它的運(yùn)行需要用到JDK安裝目錄下lib目錄中的tools.jar文件。不過(guò)我們除了安裝JDK什么也不需要做,因?yàn)镾UN已經(jīng)幫我們做好了。我們甚至不需要將tools.jar放到CLASSPATH中。
使用不帶任何的jar命令我們可以看到j(luò)ar命令的用法如下:
jar{ctxu}[vfm0M][jar-文件][manifest-文件][-C目錄](méi)文件名...
其中{ctxu}是jar命令的子命令,每次jar命令只能包含ctxu中的一個(gè),它們分別表示:
-c 創(chuàng)建新的JAR文件包
-t 列出JAR文件包的內(nèi)容列表
-x 展開(kāi)JAR文件包的指定文件或者所有文件
-u 更新已存在的JAR文件包(添加文件到JAR文件包中)
[vfm0M]中的選項(xiàng)可以任選,也可以不選,它們是jar命令的選項(xiàng)參數(shù)
-v 生成具體報(bào)告并打印到標(biāo)準(zhǔn)輸出
-f 指定JAR文件名,通常這個(gè)參數(shù)是必須的
-m 指定需要包含的MANIFEST清單文件
-0 只存儲(chǔ),不壓縮,這樣產(chǎn)生的JAR文件包會(huì)比不用該參數(shù)產(chǎn)生的體積大,但速度更快
-M 不產(chǎn)生所有項(xiàng)的清單(MANIFEST〕文件,此參數(shù)會(huì)忽略-m參數(shù)
[jar-文件]即需要生成、查看、更新或者解開(kāi)的JAR文件包,它是-f參數(shù)的附屬參數(shù)
[manifest-文件]即MANIFEST清單文件,它是-m參數(shù)的附屬參數(shù)
[-C目錄](méi)表示轉(zhuǎn)到指定目錄下去執(zhí)行這個(gè)jar命令的操作。它相當(dāng)于先使用cd命令轉(zhuǎn)該目錄下再執(zhí)行不帶-C參數(shù)的jar命令,它只能在創(chuàng)建和更新JAR文件包的時(shí)候可用。
文件名...指定一個(gè)文件/目錄列表,這些文件/目錄就是要添加到JAR文件包中的文件/目錄。假如指定了目錄,那么jar命令打包的時(shí)候會(huì)自動(dòng)把該目錄中的所有文件和子目錄打入包中。
下面舉一些例子來(lái)說(shuō)明jar命令的用法:
1)jarcftest.jartest
該命令沒(méi)有執(zhí)行過(guò)程的顯示,執(zhí)行結(jié)果是在當(dāng)前目錄生成了test.jar文件。假如當(dāng)前目錄已經(jīng)存在test.jar,那么該文件將被覆蓋。
2)jarcvftest.jartest
該命令與上例中的結(jié)果相同,但是由于v參數(shù)的作用,顯示出了打包過(guò)程,如下:
標(biāo)明清單(manifest)
增加:test/(讀入=0)(寫(xiě)出=0)(存儲(chǔ)了0%)
增加:test/Test.class(讀入=7)(寫(xiě)出=6)(壓縮了14%)
3)jarcvfMtest.jartest
該命令與2)結(jié)果類似,但在生成的test.jar中沒(méi)有包含META-INF/MANIFEST文件,打包過(guò)程的信息也略有差別:
增加:test/(讀入=0)(寫(xiě)出=0)(存儲(chǔ)了0%)
增加:test/Test.class(讀入=7)(寫(xiě)出=6)(壓縮了14%)
4)jarcvfmtest.jarmanifest.mftest
運(yùn)行結(jié)果與2)相似,顯示信息也相同,只是生成JAR包中的META-INF/MANIFEST內(nèi)容不同,是包含了manifest.mf的內(nèi)容
5)jartftest.jar
在test.jar已經(jīng)存在的情況下,可以查看test.jar中的內(nèi)容,如對(duì)于2)和3)生成的test.jar分別應(yīng)該此命令,結(jié)果如下;
對(duì)于2)
META-INF/
META-INF/MANIFEST.MF
test/
test/Test.class
對(duì)于3)
test/
test/Test.class
6)jartvftest.jar
除顯示5)中顯示的內(nèi)容外,還包括包內(nèi)文件的具體信息,如:
0WedJun1915:39:06GMT2002META-INF/
86WedJun1915:39:06GMT2002META-INF/MANIFEST.MF
0WedJun1915:33:04GMT2002test/
7WedJun1915:33:04GMT2002test/Test.class
7)jarxftest.jar
解開(kāi)test.jar到當(dāng)前目錄,不顯示任何信息,對(duì)于2)生成的test.jar,解開(kāi)后的目錄結(jié)構(gòu)如下:
==
--META-INF
`--MANIFEST
`--test
`--Test.class
8)jarxvftest.jar
運(yùn)行結(jié)果與7)相同,對(duì)于解壓過(guò)程有具體信息顯示,如:
創(chuàng)建:META-INF/
展開(kāi):META-INF/MANIFEST.MF
創(chuàng)建:test/
展開(kāi):test/Test.class
9)jaruftest.jarmanifest.mf
在test.jar中添加了文件manifest.mf,此使用jartf來(lái)查看test.jar可以發(fā)現(xiàn)test.jar中比原來(lái)多了一個(gè)manifest。這里順便提一下,假如使用-m參數(shù)并指定manifest.mf文件,那么manifest.mf是作為清單文件MANIFEST來(lái)使用的,它的內(nèi)容會(huì)被添加到MANIFEST中;但是,假如作為一般文件添加到JAR文件包中,它跟一般文件無(wú)異。
10)jaruvftest.jarmanifest.mf
與9)結(jié)果相同,同時(shí)有具體信息顯示,如:
增加:manifest.mf(讀入=17)(寫(xiě)出=19)(壓縮了-11%)
4.關(guān)于JAR文件包的一些技巧
1)使用unzip來(lái)