如果找到了对您有用的资料,烦请点击右手边的Google广告支持我继续共享知识,谢谢! http://dengpeng.spaces.live.com/

2007年4月2日星期一

Double Click to Run JAR File

Digested from Java Tip 127: See JAR run

The manifest file and the Main-Class entry

Inside most JARs, a file called MANIFEST.MF is stored in a directory called META-INF. Inside that file, a special entry called Main-Class tells the java -jar command which class to execute.

The problem is that you must properly add this special entry to the manifest file yourself—it must go in a certain place and must have a certain format. However, some of us don't like editing configuration files.


Let the API do it for you

Since Java 1.2, a package called java.util.jar has let you work with jar files. (Note: It builds on the java.util.zip package.) Specifically, the jar package lets you easily manipulate that special manifest file via the Manifest class.

Let's write a program that uses this API. First, this program must know about three things:

1. The JAR we wish to make runnable
2. The main class we wish to execute (this class must exist inside the JAR)
3. The name of a new JAR for our output, because we shouldn't simply overwrite files

Write the program

The above list will constitute our program's  arguments. At this point, let's choose a suitable name for this application. How does MakeJarRunnable sound?
Check the arguments to main

Assume our main entry point is a standard main(String[]) method. We should first check the program arguments here:

    if (args.length != 3) {
System.out.println("Usage: MakeJarRunnable "+ "<jar file> <Main-Class><output>");
System.exit(0);
}

Please pay attention to how the argument list is interpreted, as it is important for the following code. The argument order and contents are not set in stone; however, remember to modify the other code appropriately if you change them.



Access the JAR and its manifest file


First, we must create some objects that know about JAR and manifest files:

    //Create the JarInputStream object, and get its manifest
JarInputStream jarIn = new JarInputStream(new FileInputStream(args[0]));
Manifest manifest = jarIn.getManifest();
if (manifest == null) {
//This will happen if no manifest exists
manifest = new Manifest();
}

Set the Main-Class attribute

We put the Main-Class entry in the manifest file's main attributes section. Once we obtain this attribute set from the manifest object, we can set the appropriate main class. However, what if a Main-Class attribute already exists in the original JAR? This program simply prints a warning and exits. Perhaps we could add a command-line argument that tells the program to use the new value instead of the pre-existing one:

    Attributes a = manifest.getMainAttributes();
String oldMainClass = a.putValue("Main-Class", args[1]);
//If an old value exists, tell the user and exit
if (oldMainClass != null) {
System.out.println("Warning: old Main-Class value is: "
+ oldMainClass);
System.exit(1);
}

Output the new JAR

We need to create a new jar file, so we must use the JarOutputStream class. Note: We must ensure we don't use the same file for output as we do for input. Alternatively, perhaps the program should consider the case where the two jar files are the same and prompt the user if he wishes to overwrite the original. However, I reserve this as an exercise for the reader. On with the code!

    System.out.println("Writing to " + args[2] + "...");
JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(args[2]),manifest);
We must write every entry from the input JAR to the output JAR, so iterate over the entries:
    //Create a read buffer to transfer data from the input
byte[] buf = new byte[4096];
//Iterate the entries
JarEntry entry;
while ((entry = jarIn.getNextJarEntry()) != null) {
//Exclude the manifest file from the old JAR
if ("META-INF/MANIFEST.MF".equals(entry.getName())) continue;
//Write the entry to the output JAR
jarOut.putNextEntry(entry);
int read;
while ((read = jarIn.read(buf)) != -1) {
jarOut.write(buf, 0, read);
}
jarOut.closeEntry();
}
//Flush and close all the streams
jarOut.flush();
jarOut.close();
jarIn.close();

Complete program

Of course, we must place this code inside a main method, inside a class, and with a suitable set of import statements. The Resources section provides the complete program.



Usage example


Let's put this program to use with an example. Suppose you have an application whose main entry point is in a class called HelloRunnableWorld. (This is the full class name.) Also assume that you've created a JAR called myjar.jar, containing the entire application. Run MakeJarRunnable on this jar file like so:

java MakeJarRunnable myjar.jar HelloRunnableWorld myjar_r.jar

Again, as mentioned earlier, notice how I order the argument list. If you forget the order, just run this program with no arguments and it will respond with a usage message.

Try to run the java -jar command on myjar.jar and then on myjar_r.jar. Note the difference! After you've done that, explore the manifest files (META-INF/MANIFEST.MF) in each JAR. (You can find both JARs in the source code.)

Here's a suggestion: Try to make the MakeJarRunnable program into a runnable JAR!



Run with it


Running a JAR by double-clicking it or using a simple command is always more convenient than having to include it in your classpath and running a specific main class. To help you do this, the JAR specification provides a Main-Class attribute for the JAR's manifest file. The program I present here lets you utilize Java's JAR API to easily manipulate this attribute and make your JARs runnable.

source code and JARs for this tip

7 条评论:

123 说...

搬家公司坐月子中心 坐月子中心台中 台北搬家公司 新竹搬家公司 桃園搬家公司 桃園房屋買賣 桃園房屋仲介 桃園房屋買賣 桃園房屋仲介 乳癌 全身健康檢查 自由行 三久 太陽能 三久太陽能 慈善機構 租辦公室 買辦公室 素食餐廳 氣球佈置 二手車 健檢 醫學美容 淨膚雷射 汽車美容 法拍屋 水餃 清潔公司 塑膠袋批發 塑膠袋工廠 實驗動物 到府坐月子 Disposable plastic cups Disposable products 宜蘭住宿坐月子中心 坐月子餐 孕婦 月子餐 美國月子中心 frying machine 團體服 OBU 投審會 google關鍵字廣告 會計師事務所 會計師 工商登記 彌月蛋糕 公司登記 保時捷 法拉利 福利 <包子 肉粽 宅配美食

123 说...

四神湯 搬家公司 訂房網 花東旅遊 桃園土地 桃園房屋仲介 巴里島 到府坐月子 中古車 坐月子中心台北 台北人力銀行 三久麻糬
創業加盟 水餃 壯陽食品 櫻花牌熱水器 素食月子餐 香港自由行 化妝品盒 湯包 桃園房屋 桃園房屋網 通馬桶 抽水肥 包通 馬桶不通 通馬桶 通水管 DC Jack tact switch Slide switch Phone Jack USB connector RCA Jack 開 關 製網 菱形網 不鏽鋼網 金屬網 無塵室射出 Disposable plastic cups Oem代工廠 breading machine vegetable machine ECO products Biodegradable plastic PLA 律師事務所 律師 寵物醫院 polylactic acid Plastic injection Mold development Injection Mold Plastic injection molding led招牌

123 说...

Injection molding ISO9001認證 射出成形 塑膠製成品 塑膠模具設計 模具開發 精密射出 縫衣機塑件 Industrial PCB Heavy Copper PCB Microwave PCB Medical PCB 醫學美容診所 肉毒桿菌 肉毒桿菌瘦臉 醫學美容 整型診所 美國月子中心 徵信 徵信公司 網路行銷 食品批發 交友太陽能熱水器 環保袋 慈善基金會婚友 婚友社 婚友聯誼 愛情公寓 相親 相親銀行 聯誼 命理網 姓名學 Hook and Loop 婚禮佈置 太陽能熱水器 中華湯包 菱型網 不鏽鋼 壯陽 成人用品裝潢 裝潢工程 房屋裝潢春藥 壯陽藥品 持久 手工水餃 中華湯包 104法拍網 信義房屋 新竹花店 婚友聯誼社 Odm 印刷 彩色印刷

123 说...

早洩 漆彈 情趣用品 湯包 宜蘭民宿 宜蘭住宿 網路訂房 宜蘭飯店 新娘祕書 清潔公司 植牙 裝潢 室內設計 油漆粉刷 油漆工 油漆工程 洗鞋加盟 洗包包加盟 洗包包 創業加盟店 早餐店加盟 開店創業 創業開店 結婚金飾 鑽石婚戒 通水管 通水管 出軌 清潔公司 台北搬家公司 整形 韓風整形 整形 韓風整形 老人癡呆症 情緒管理 訂房網 線上訂房 室內裝潢 > 舊屋翻新 裝潢施工 木工裝潢mini usb情人花束 催情 增大 模具廠 居家裝潢 團購美食 裝潢設計 馬桶 馬桶不通 國外旅遊 國外機票 團體旅遊 直航機票 簽證 熱水器 蘭花 化糞池 抽化糞池 抽水肥

123 说...

水管不通> 馬桶 馬桶不通 上順旅行社 五福旅行社 大興旅行社 天喜旅行社 天福旅行社 日本旅行社 日本旅遊 會場設計 紙盒訂裝 展覽設計 便宜機票 展場設計 二手車 中古車 展場設計 展覽設計 消防設備 消防設備 機電 崴立機電 牙齒美白 特色餐廳 景觀餐廳 親子餐廳 植牙 牙周病治療方法 白內障 心絲蟲 腎衰竭 狗皮膚病 RF PCB 植牙費用 牙周病 光纖美白除毛 肉毒桿菌除皺 便宜機票 國內旅遊 紙袋包裝 當鋪 當舖 拉麵 T恤 慈善 店面租賃 店面出租 店面出售 Plastic Drinking Cups 宜蘭民宿 花茶 花草茶 肝癌 健康檢查 身體檢查 飛梭雷射 雷射溶脂 直航機票 養生茶 招牌 台北法拍屋 會場佈置

123 说...

洗鞋加盟 酒店式公寓 旅行社 slot machine manufacturer 杭州旅遊 北京自由行 上海自由行 旅遊網 律師 台北民宿 手提紙袋 紙袋工廠 包裝紙袋 手提袋 包裝盒 股票教學 股市分析 股市億萬贏家 股票軟體 股票行情 太陽能 日本訂房 包通 彌月禮盒 塑膠射出成型 iso認證 iso 團體旅遊 商用不動產 辦公室 台北辦公室 辦公室出租 廠辦 安泰登峰 汽車美容 風水擺設 風水 居家風水 工廠風水 陽宅 命理風水 陽宅風水 勘輿 風水地理 簽證 保養 美國月子中心 slot game machine slot machine cabinet Bmw 中古車買賣 汽車借款 gaming machine manufacturer 班服

123 说...

招牌製作 ferrari 婚禮 禮服 結婚 婚紗照 婚紗攝影 無刀雷射 雷射近視 眼睛雷射 近視雷射 眼科 近視雷射 眼科 近視 眼科 美國 歐洲 印度 義大利 英國 法國 西班牙 京都 東京 埃及 房屋買賣 賓士 lexus 紙袋印刷 會場設計 貸款 票貼 二胎 包裝紙盒 融資 工商融資 支票貼現日本機票 日本自由行 搬家公司 借款 法律事務所 馬桶不通 food forming patty machine boiling machine 化妝品包 裝 紙盒 消毒 離婚 洗水塔通水管獸醫院 寵物住宿 通馬桶 Rigid-Flex PCB 動物醫院 洗鞋店