分享
 
 
 

用java -jar命令运行你的JARs

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

摘要

这篇技巧显示了如何将一个不可获取的Java档案(JAR)变成可获取的,而没必要直接操作列表文件。你将学习开发一个短程序能使任何JAR用java –jar命令运行或在一个象Widnows操作系统上用双击操作使其运行。

你能够容易地将一个应用程序的整个类及资源打包进一个Java档案(JAR)。实际上,这是jar文件的其中一个目的。另一个目的是让用户容易执行存贮在档案中的应用程序。为什么当它们能够作为第一类正确依靠本地执行时,jar文件在Java世界中仍仅作为档案功能被看成第二类成员?

要执行一个jar文件,你可以使用java命令中的-jar选项。例如,说你有一个可获取的jar文件叫myjar.jar,这是因为这个文件是可获取的,你能够象这样执行它:java -jar myjar.jar.。

换句话说,当在一个象微软Windows操作系统上安装的Java运行环境(JRE)中,你能够通过双击JVM相关的jar文件来运行应用程序。这些JARs就一定是可获取的。

问题是:你怎样使一个JAR可获取?

清单文件和main-类入口

在多数JARs中,一个叫作MANIFEST.MF的文件存贮在一个叫作META-INF的目录中。在那些文件中,一个叫作Main-类的专门入口告诉java –jar命令哪个类将要被执行。

问题是你必须自己正确地将这些专门的入口添加到清单文件中——它必须在一个特定的地方并且具有一种特定的格式。然而,我们其中一些人不喜欢编辑配置文件。

让API为你作这些

自从Java 1.2以来,一个叫java.util.jar的包让你与jar文件一起工作。(注意:它是在java.util.zip包上建立的),jar包让你很容易地经由Manifest类操作专门的清单文件。

让我们用这个API写一个程序。首先,这个程序必须了解三件事情:

1.我们希望使能够被获取的JAR

2.我们希望被执行的main类(这个类必须存在于JAR中)

3.我们输入的新JAR的名称,因为我们不能简单地覆盖文件

写程序

上面的列表将组成我们程序的参数。基于这一点,让我们为这个程序选择一个合适的名称。MakeJarRunnable 怎么样?

检查main的参数

假设我们的主入口点是一个标准的main(String[])方法。我们首先应该在这里检查程序的参数:

if (args.length != 3) {

System.out.println("Usage: MakeJarRunnable "

+ "<jar file> <Main-Class>

<output>");

System.exit(0);

}

请注意参数列表是怎样说明的,这对于下面的代码是十分重要的。参数顺序及内容在这里没有被设置,然而,假如你要改变它们记住相应地修改其它代码。

访问JAR和它的清单文件

首先,我们必须创建一些了解JAR和清单文件的对象:

//创建JarInputStream对象并获取它的清单

JarInputStream jarIn = new JarInputStream(new FileInputStream(args[0]));

Manifest manifest = jarIn.getManifest();

if (manifest == null) {

//如果没有清单存在,下面代码将被执行

manifest = new Manifest();

}

设置Main-类的属性

我们将Main-类入口放进清单文件的main属性部份。一旦我们从清单对象中获得这个属性设置,我们就能设置适当的main类。然而,如果一个Main-类属性已经存在于原JAR 中怎么办?这个程序会简单地输出一个警告并退出。也许我们能够加一个命令行参数告诉程序用新的值代替先前存在的那个:

Attributes a = manifest.getMainAttributes();

String oldMainClass = a.putValue("Main-Class", args[1]);

//如果一个旧值存在,告诉用户并退出

if (oldMainClass != null) {

System.out.println("Warning: old Main-Class value is: "

+ oldMainClass);

System.exit(1);

}

输出新JAR

我们需要创建一个新jar文件,所以我们必须使用JarOutputStream类。注意:我们必须确保输出和输入不会使用同一文件。换句话说,也许程序应该考虑两个jar文件一样的情况并提示用户是否他希望覆盖原文件。然而,我将这作为读者的练习保留。开始代码!

System.out.println("Writing to " + args[2] + "...");

JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(args[2]),

manifest);

我们必须从输入JAR到输出JAR写每一个入口,因此重申上述入口:

//创建一个读缓冲以便从输入处传输数据

byte[] buf = new byte[4096];

//重申入口

JarEntry entry;

while ((entry = jarIn.getNextJarEntry()) != null) {

//从旧JAR中排出清单文件

if ("META-INF/MANIFEST.MF".equals(entry.getName())) continue;

//为输出JAR写一个入口

jarOut.putNextEntry(entry);

int read;

while ((read = jarIn.read(buf)) != -1) {

jarOut.write(buf, 0, read);

}

jarOut.closeEntry();

}

//刷新并关闭所有流

jarOut.flush();

jarOut.close();

jarIn.close();

完成程序

当然,我们必须将这段代码放到一个类的main方法中,并且使用一个适当的输入声明设置。源程序部分提供完整程序。

使用范例

让我们用一个例子将这段程序投入实际使用。假设你已经有了一个应用程序其main入口点是在一个叫HelloRunnableWorld的类中(这是类的全称)。同时假设你已经创建了一个叫myjar.jar的JAR文件,包含整个应用程序。象下面一样在这个jar文件中运行MakeJarRunnable:

java MakeJarRunnable myjar.jar HelloRunnableWorld myjar_r.jar

象前面提到的一样,再次注意我是怎样给参数列表排序的。如果你忘记了顺序,正好没有使用参数运行这个程序,它会响应一个用法消息。

试着在myjar.jar上运行java -jar 命令,然后在myjar_r.jar上运行。注意不同的地方!这样做了以后,在每一个JAR中浏览清单文件(META-INF/MANIFEST.MF)。(你可以在源代码中找到这两个JARs)

这有一个建议:试着将MakeJarRunnable程序放进一个可获取的JAR中!

运行

通过双击或使用一个简单命令运行一个JAR总比不得不将其包含在你的类路径中并运行一个特别的main类要方便。要帮助你做到这点,JAR规范为JAR的清单文件提供了一个Main-类属性。这里我所介绍的程序让你使用Java的JAR API很轻松地操作这一属性并使你的JARs可获取。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有