java之学习笔记(26)----------jar

jar文件就是Java Archive File,顾名思义,它的应用是与java息息相关的。jar文件就是一种压缩文件,与常见的ZIP压缩文件格式兼容,习惯上称之为jar包。jar命令时随JDK自动安装的,存放在JDK安装目录下的bin目录中,Windows下的文件名为jar.exe,Linux下的文件名为jar.下面简单说一个常用的jar命令:

 1、jar cf test.jar test

    该命令没有执行过程的显示,执行结果是在当前目录生成了test.jar文件。如果当前目录已经存在test.jar文件,那么该文件将被覆盖。

 2、jar cvf test.jar test

    该命令与1中的命令结果相同,但是由于v参数的作用,显示出了打包过程的详细信息。

 3、jar tf test.jar

    该命令显示出jar文件中包含的所有目录和文件名列表。

 4、jar tvf test.jar

    该命令除了显示包含的目录和文件名外,还显示了各目录和文件的大小、创建时间等详细信息。

 5、jar xf test.jar

    解压test.jar到当前目录,不显示任何信息。

 6、jar xvf test.jar

    解压test.jar到当前目录,并显示出解压过程的详细信息。

 7、使用重定向

    如果想查看jar文件的内容,但是jar文件很大,包含的类很多,这时查看可能会因为显示出的文件过多,屏幕刷新的速度过快 ,而不能正常浏览,这里就以rt.jar文件为例,,它里面包含种类繁多的类文件要想查看详细的信息,就使用dos命令的重定向功能,将显示到屏幕上的内容定向到一个文件中。只需要执行jar tvf rt.jar>c:\rt.txt即可在c盘根目录下生成一个rt.txt文本文件。以后要想查看rt.jar的内容,只需要查看c盘根目录下的rt.txt文件的内容就可以了。

这个技巧阐明了如何不直接处理清单文件而将一个不能运行jar包转换成一个可以执行的jar包。学会如何写一段转换jar包的程序,将你的jar包转换成你能使用java -jar 命令运行jar包或象在windows系统上那样通过双击来运行jar包。

[@more@] 
你可以很容易地将一个应用的所有的类和资源打包到一个jar文件中去。事实上,这只是打包的一个原因。另一个原因是让用户很容易地执行包中的应用。那么在java的世界里,为什么jar是第二类公民――仅仅用作打包――当他们能成为第一类公民的时候,能和本地执行程序一样吗?

如果想执行jar文件,可以使用java命令的-jar选项。例如,你有一个可以运行的myjar.jar文件。因为该文件是可以执行的,所以你可以用如下命令执行之:java –jar myjar.jar。此外,安装在windows JRE将会把jar文件和JVM关联起来,以便通过双击来运行jar应用。

现在的问题是:如何把jar做成可以运行的包?

清单文件和主类条目

在大多数jar文件中,在目录META-INF里有个叫MANIFEST.MF的文件。在该文件中,有一个叫Main-Class的特殊条目,它说明了java -jar命令执行的类。

问题是你必须正确地在清单文件中加入这个特殊的条目――它必须是在特定的位置和特定的格式。可是,好多人不喜欢修改配置文件。

用API修改改配置

从java1.2之后,一个叫java.util.jar的包可以操作jar文件(注:它架构在java.util.zip包之上)。Jar包能让你通过Manifest类很容易地操作专门的清单文件。

让我们使用这些API写一个程序。首先,这个程序必须知道三件事:

  1. 我们想让它执行的jar文件;

  2. 我们想执行的main类(这个文件必须存在于jar包中);

  3. 我们要输出的新jar包的名称,因为不是简单地覆盖原文件;

编写代码

上面的列表将组成我们程序的参数。在这里,让我们选择一个合适名字,MakeRunnable咋样?

检查送入main的参数

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

if (args.length != 3) {

    System.out.println("Usage: MakeJarRunnable "


                       + "<jar file> <Main-Class>

”);

    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-Class条目放到清单文件里main属性部分。一旦我们从mainfest对象中得到这个属性集,我们就能设置合适的main类。然而,如果Main-Class属性存在于原始的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类。注意:我们必须确保输出文件和输入文件不相同。作为可选方案,应该考虑如果两个文件同名,程序应该提示用户是否覆盖原始文件。我将这个作为练习留给读者。下面是代码。 
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包,它包含了整个应用。在这个包上运行MakeJarRunnable,如下所示:

java MakeJarRunnable myjar.jar HelloRunnableWorld myjar_r.jar

此外,如前所述,注意我是如何安排参数列表顺序的。如果你忘记了顺序,运行一下这个不带参数的程序,它将会显示一个用法信息。

试着用java -jar命令运行myjar.jar文件,之后在myjar_r.ja文件上。注意他们的不同!完成之后,研究在每一个jar包中的清单文件(META-INF/MANIFEST.MF)。

建议:试着将MakeJarRunnable制作成一个可以运行的Jar文件!

用它处理你想运行的jar包

通过双击或者使用简单的命令运行一个jar包,总是要比把它放到管理员在2009年8月13日编辑了该文章文章。 
–> 
1.其实命令比较简单:进入相应的目录后,执行java -jar XXX.jar即可!

2.但是,为什么通过Maven打包或者Eclipse export出来的jar不能运行呢?原因很简单,没指定执行哪个类的main方法,如何指定?配置文件,项目文件夹下有一个META-INF文件夹,META-INF文件夹下有一个MANIFEST.MF文件,只要更改该文件就可以了

3.默认该文件内容是:

Manifest-Version: 1.0 
Created-By: 1.4.2(Sun Microsystems Inc.)

将其改成

Manifest-Version: 1.0 
Created-By: 1.4.2(Sun Microsystems Inc.) 
Main-Class: XXX.XXX.XXX.XXX

注意:

Main-Class后面X部分是包名.类名

Main-Class:后面有个空格,下面还有空的一行

4.改好内容后,怎么将其打成jar包呢?

我试过,直接用winrar打包,然后改后缀名,不行,

以下这种方法可行:

假设你的jar包名为myJar.jar:

(1)先将myJar.jar解压至myJar(在同一层文件夹)

(2)进入myJar文件夹,再进入META-INF文件夹,更改MANIFEST.MF文件,

    按照步骤三的操作即可 

(3)保存后退到myJar.jar同一层目录,然后执行jar umf myJar/META-INF/MANIFEST.MF myJar.jar

    如果没报错,并生成了XXX.tmp文件,就说明执行成功, 

    打开myJar.jar就可以看到MANIFEST.MF文件已经被改成了相应的需要的文件了 

(4)在当前目录执行java -jar myJar.jar即可

良心的公众号,更多精品文章,不要忘记关注哈

《Android和Java技术栈》


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值