您可以輕松地將應用程序的壹組類文件和資源文件打包到壹個JAR中。事實上,這是jar文件的壹個目的。另壹個目的是讓用戶可以輕松地執行打包到jar文件中的應用程序。那麽為什麽jar文件作為壹個文件在整個java中只占據次要地位,而本地執行卻被忽略了呢?
要執行jar文件,可以使用java命令的-jar選項。例如,假設您有壹個名為myjar.jar的文件,這個jar可以運行,您可以運行它:java-jarmyjar.jar另壹種方法是,當JavaRuntimeEnvironment(JRE)已經安裝在windows之類的操作系統上時,雙擊jar來運行這個應用程序,並將jar文件與JVM相關聯(將java.exe與jar文件相關聯)。當然,jar文件必須是可執行的。
現在的問題是:如何制作壹個可執行的jar?
清單文件和主類條目。
在大多數jar中,壹個名為MANIFEST的文件。MF保存在壹個名為META-INF的目錄中。在那個文件裏,
包含壹個名為Main-Class的特殊條目,它告訴java-jar命令要執行哪個類。
問題是,您必須為清單文件手動添加適當的條目,並且它們必須位於特定的位置並采用特定的格式。遺憾的是,並不是所有人都喜歡打開寫字板編輯配置文件。
讓API幫妳完成任務。
自從java1.2發布之後,出現了壹個名為java.uil.jar的包,可以讓妳方便的處理jar文件。(註意:這個包基於java.util.zip)特別是,jar包允許您通過Mainfest類輕松地操作那些清單文件。
讓我們用這個API寫壹個程序。首先,程序必須知道三件事:
1。我們想要使之可操作的jar文件。
2。運行jar的主類(這個類必須包含在jar中)。
3。輸出新jar文件的文件名,因為我們不能簡單地覆蓋原始文件。
編寫程序
上面列出的三個要求將構成我們程序的參數。現在,讓我們為這個程序選擇壹個合適的名稱。
MakeJarRunnable聽起來怎麽樣?
檢查主方法的參數
假設我們的main方法的入口點是壹個標準的main(String[])方法。我們應該像這樣檢查程序的參數:
if(args.length!=3){
System.out.println("用法:MakeJarRunnable " " & ltjarfile & gt& ltmain-Class & gt;& lt輸出>);
system . exit(0);
}
請註意參數列表是如何描述的,因為這在下面的代碼中非常重要。參數的順序和內容不固定;
但是,如果您想要更改它們,請記住相應地修改其他代碼。
訪問jar和jar清單文件
首先,我們必須創建壹些理解jar和manifest的對象:
//CreatetheJarInputStreamobject和getitsmanifest
JarInputStreamjarIn = newJarInputStream(newfile inputstream(args[0]));
manifest manifest = jarin . get manifest();
if(manifest==null){
//thislwilllionifnomanifestexists
manifest = new manifest();
}
設置主類屬性。
我們將主類條目放在清單文件的主屬性部分。壹旦從manifest對象中獲得該屬性,就可以設置所需的mainclass。但是,如果原始jar中已經存在main-Class屬性,該怎麽辦呢?這裏我們簡單地輸出壹個警告,然後退出。我們可以添加壹個命令行參數來告訴程序使用新值而不是舊值:
attributes a = manifest . getmainattributes();
StringoldMainClass = a . put value(" Main-Class ",args[1]);
//Ifanoldvalueexists,telltheuserandexit
if(oldMainClass!=null){
System.out.println("警告:oldMain-Classvalueis:"
oldMainClass);
system . exit(1);
}
輸出新的JAR。
我們需要創建壹個新的JAR文件,所以我們必須使用JarOutputStream類。註意:
我們必須確保不使用與輸入文件相同的名稱作為輸出文件的名稱。另壹個解決方案是,程序應該考慮到兩個jar文件是相同的這壹事實,並且如果用戶願意的話,敦促他覆蓋原始文件。然而,我保留了這個作為讀者的練習。從下面的代碼開始:
system . out . println(" writing to " args[2]" ... ");
JarOutputStreamjarOut = newJarOutputStream(newFileOutputStream(args[2]),manifest);
我們必須將每個條目從輸入JAR寫到輸出JAR,所以我們叠代每個條目:
//createaradbufferttransferdatafromtheinput
byte[]buf = new byte[4096];
//叠代條目
JarEntryentry
while((entry = jarin . getnextjarentry())!=null){
//ExcludethemanifestfilefromtheoldJAR
if("META-INF/MANIFEST。MF”。equals(entry.getName()))繼續;
//WritetheentrytotheoutputJAR
jarout . putnextentry(entry);
intread
while((read=jarIn.read(buf))!=-1){
jarOut.write(buf,0,read);
}
jarout . close entry();
}
//flushandclosealthstreams
jarout . flush();
jarout . close();
jarin . close();
完成程序
當然,我們要把這段代碼放在壹個類的main方法中,需要大量的導入代碼。完整計劃:
/Java world/Java tips/Java tip 127/makejarrunnable . zip
程序使用示例
讓我們將這個程序應用到壹個例子中。假設您有壹個應用程序,它的入口點是壹個名為HelloRunnableWorld的類,假設您創建了壹個名為myjar.jar的jar,它包含了整個程序。運行MakeJarRunnable:
javamakejarrunnablemyjar . jarhellorunnableworldmyjar _ r . jar
如前所述,註意我的參數順序。如果您忘記了順序,並且在沒有參數的情況下運行程序,它將會給出壹個使用提示。
嘗試在myjar.jar上運行java-jar命令,然後在myjar_r.jar上運行,註意區別!好了,妳完成了這壹切,瀏覽清單文件(META-INF/MANIFEST。MF)。