使用JAR文件
JAR文件的全称是 Java Archive File,意思就是Java档案文件。通常JAR文件是一种压缩文件,与常见的ZIP压缩文件兼容,通常也被称为JAR包。JAR文件与ZIP文件的区别就是在JAR文件中默认包含了一个名为META-INF/MANIFEST.MF 的清单文件,这个清单文件是在生成JAR文件时由系统自动创建的。
当开发了一个应用程序后,这个应用程序包含了很多类,如果需要把这个应用程序提供给别人使用,通常会将这些类文件打包成一个JAR文件,把这个JAR文件提供给别人使用。只要别人在系统的CLASSPATH环境变量中添加这个JAR文件,则Java虚拟机就可以自动在内存中解压这个JAR包,把这个JAR文件当成一个路径,在这个路径中查找所需要的类或包层次对应的路径结构。
使用JAR文件有以下好处。
- 安全。能够对JAR文件进行数字签名,只让能够识别数字签名的用户使用里面的东西。
- 加快下载速度。在网上使用 Applet时,如果存在多个文件而不打包,为了能够把每个文件都下载到客户端,需要为每个文件单独建立一个HTTP连接,这是非常耗时的工作。将这些文件压缩成一个JAR包,只要建立一次HTTP连接就能够一次下载所有的文件。
- 压缩。使文件变小,JAR的压缩机制和ZIP完全相同。
- 包封装。能够让JAR包里面的文件依赖于统一版本的类文件。
- 可移植性。JAR包作为内嵌在Java平台内部处理的标准,能够在各种平台上直接使用。
把一个JAR文件添加到系统的 CLASSPATH环境变量中后,Java将会把这个JAR文件当成一个路径来处理。实际上JAR文件就是一个路径,JAR文件通常使用jar命令压缩而成,当使用jar命令压缩生成JAR文件时,可以把一个或多个路径全部压缩成一个JAR文件。
例如,test目录下包含如下目录结构和文件。
如果把上面test路径下的所有文件压缩成一个JAR文件,则JAR文件的内部目录结构为
jar命令详解
jar 是随JDK自动安装的,在JDK安装目录下的bin目录中,Windows下文件名为 Jar.exe,Linux下文件名为jar。运行它需要用到JDK安装目录下lib目录中的 tools.jar文件,通常系统会自动加载tools.jar,无须显式设置。
如果在命令行窗口运行不带任何参数的jar命令,系统将会提示jar命令的用法。
C:\Users\yuanyu>jar
用法: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...
选项:
-c 创建新档案
-t 列出档案目录
-x 从档案中提取指定的 (或所有) 文件
-u 更新现有档案
-v 在标准输出中生成详细输出
-f 指定档案文件名
-m 包含指定清单文件中的清单信息
-n 创建新档案后执行 Pack200 规范化
-e 为捆绑到可执行 jar 文件的独立应用程序
指定应用程序入口点
-0 仅存储; 不使用任何 ZIP 压缩
-P 保留文件名中的前导 '/' (绝对路径) 和 ".." (父目录) 组件
-M 不创建条目的清单文件
-i 为指定的 jar 文件生成索引信息
-C 更改为指定的目录并包含以下文件
如果任何文件为目录, 则对其进行递归处理。
清单文件名, 档案文件名和入口点名称的指定顺序
与 'm', 'f' 和 'e' 标记的指定顺序相同。
示例 1: 将两个类文件归档到一个名为 classes.jar 的档案中:
jar cvf classes.jar Foo.class Bar.class
示例 2: 使用现有的清单文件 'mymanifest' 并
将 foo/ 目录中的所有文件归档到 'classes.jar' 中:
jar cvfm classes.jar mymanifest -C foo/ .
下面通过一些例子来说明jar命令的用法。
1.创建JAR文件:jar cf test.jar test
该命令没有显示压缩过程,执行结果是将当前路径下的 test 路径下的全部内容生成一个 test.Jar文件。如果当前目录中已经存在 test.Jar文件,那么该文件将被覆盖。
2.创建JAR文件,并显示压缩过程:jar cvf test.jar test
该命令的结果与第1个命令相同,但是由于v参数的作用,显示出了打包过程,如下所示
4.自定义清单文件内容:jar cvfm test.jar manifest.mf test
运行结果与第2个命令相似,显示信息也相同,其中 m 选项指定读取用户清单文件信息。因此在生成的JAR包中清单文件META-INF/MANIFEST.MF 的内容有所不同,它会在原有清单文件基础上增加 MANIFEST.MF 文件的内容。
当开发者向 MANIFEST.MF 清单文件中增加自己的内容时,就需要借助于自己的清单文件了,清单文件只是一个普通的文本文件,使用记事本编辑即可。清单文件的内容由如下格式的多个 key-value对组成。
key:<空格>value
清单文件的内容格式要求如下:
- 每行只能定义一个 key-value对,每行的 key-value对之前不能有空格,即key-value对必须顶格写。
- 每组key-value对之间以“: ”(英文冒号后紧跟一个英文空格)分隔,少写了冒号或者空格都是错误的。
- 文件开头不能有空行。
- 文件必须以一个空行结束。
可以将上面文件保存在任意位置,以任意文件名存放。例如将上面文件保存在当前路径下,文件名为a.txt。使用如下命令即可将清单文件中的key-value对提取到 META-INF/MANIFEST.MF文件中。
jar cvfm test.jar a.txt test
5.查看JAR包内容:jar tf test.jar
在 test.jar 文件已经存在的前提下,使用此命令可以查看 test.jar 中的内容。例如,对使用第2个命令生成的 test.jar 执行此命令,结果如下:
当JAR包中的文件路径和文件非常多时,直接执行该命令将无法看到包的全部内容(因为命令行窗口能显示的行数有限),此时可利用重定向将显示结果保存到文件中。例如,采用如下命令:
jar tf test.jar > a.txt
执行上面命令看不到任何输出,但命令执行结束后,将在当前路径下生成一个 a.txt 文件,该文件中保存了 test.Jar 包里文件的详细信息。
6.查看JAR包详细内容:jar tvf test.jar
该命令与第5个命令基本相似,但它更详细。所以除了显示第5个命令中显示的内容外,还包括包类文件的详细信息。例如:
7.解压缩:jar xf test.jar
将 test.jar文件解压缩到当前目录下,不显示任何信息。假设将第2个命令生成的 tes.Jar 解压缩,将看到如下目录结构:
8.带提示信息解压缩:jar xvf test.jar
解压缩效果与第7个命令相同,但系统会显示解压过程的详细信息。例如:
9.更新JAR文件:jar uf test.jar Hello.class
更新 test.jar中的 Hello.class文件。如果 test.jar 中已有 Hell.class 件,则使用新的 Hell.class文件替换原来的 Hell.class 文件;如果 test.jar 中没有 Hello.class文件,则把新的 Hello.class文件添加到test.jar文件中。
10.更新时显示详细信息:jar uvf test.jar Hello.class
这个命令与第9个命令相同,也用于更新 test.Jar文件中的 Hello.class文件,但它会显示详细的压缩信息。例如:
创建可执行的JAR包
当一个应用程序开发成功后,大致有如下三种发布方式。
当用户单击上面的批处理文件时,系统将执行批处理文件的java命令,从而运行程序的主类。如果不想保留运行Java程序的命令行窗口,也可在批处理文件中定义如下命令:
- 使用平台相关的编译器将整个应用编译成平台相关的可执行性文件。这种方式常常需要第三方编译器的支持,而且编译生成的可执行性文件丧失了跨平台特性,甚至可能有一定的性能下降。
- 为应用编辑一个批处理文件。以 Windows操作系统为例,批处理文件中只需要定义如下命令:
- 将一个应用程序制作成可执行的JAR包,通过JAR包来发布应用程序。
把应用程序压缩成JAR包来发布是比较典型的做法,如果开发者把整个应用制作成一个可执行的JAR包交给用户,那么用户使用起来就方便了。在 Windows下安装JRE时,安装文件会将 *jar 文件映射成由 javaw.exe打开。对于一个可执行的JAR包,用户只需要双击它就可以运行程序了,和阅读 *chm 文档一样方便(*,chm文档默认是由hh.exe打开的)。下面介绍如何制作可执行的JAR包。
创建可执行的JAR包的关键在于:让 javaw 命令知道JAR包中哪个类是主类,javaw 命令可以通过运行该主类来运行程序。
jar命令有一个 -e 选项,该选项指定JAR包中作为程序入口的主类的类名。因此,制作一个可执行的JAR包只要增加 -e 选项即可。例如如下命令:
jar cvfe test.jar test.Test test
上面命令把test目录下的所有文件都压缩到 test.jar 包中,并指定使用 test.Test 类(如果主类带包名,此处必须指定完整类名)作为程序的入口。
运行上面的JAR包有两种方式。
- 使用 java 命令,使用 java 运行时的语法是:java -jar test.jar。
- 使用 javaw 命令,使用 javaw 运行时的语法是:javaw test.jar。
当创建 JAR 包时,所有的类都必须放在与包结构对应的目录结构中,就像上面 -e 选项指定的Test类,表明入口类为Test。因此,必须在 JAR 包下包含 Test.class文件。
关于JAR包的技巧
介绍JAR文件时就已经说过,JAR文件实际上就是ZIP文件,所以可以使用一些常见的解压缩工具来解压缩JAR文件,如 Windows下的 WinRAR、WinZip等,以及 Linux下的 unzip等。使用 WinRAR和 WinZip等工具比使用JAR命令更加直观、方便;而使用 unzip则可通过 -d 选项来指定目标目录。
解压缩一个JAR文件时不能使用 jar 的 -C 选项来指定解压的目标目录,因为 -C 选项只在创建或者更新包时可用。如果需要将文件解压缩到指定目录下,则需要先将该JAR文件拷贝到目标目录下,再进行解压缩。如果使用 unzip,就无须这么麻烦了,只需要指定一个-d 选项即可。例如:
unzip test.jar -d dest/
使用 WinRar则更加方便,它不仅可以解压缩JAR文件,而且便于浏览JAR文件的任意目录。图6.12显示了使用 WinRAR查看 test.jar 包的界面。
如果不喜欢jar命令的字符界面,也可以使用 WinRAR工具来创建JAR包。因为WinRAR工具创建压缩文件时不会自动添加清单文件,所以需要手动添加清单文件,即需要手动建立META-INF路径,并在该路径下建立一个 MANIFEST.MF 文件,该文件中至少需要如下两行:
上面的 MANIFEST.MF 文件是一个格式敏感的文件,该文件的格式要求与前面自定义清单的格式要求完全一样。
接下来选中需要被压缩的文件、文件夹和META-NF文件夹,单击右键弹出右键菜单,单击“添加到压缩文件(A)…”菜单项,将看到如图6.13所示的压缩界面。
按图 6.13 选择压缩成 ZIP 格式,并输入压缩后的文件名,然后单击“确定”按钮,即可生成一个JAR包,与使用jar命令生成的JAR包没有区别。
除此之外,Java还可能生成两种压缩包:WAR包和EAR包。其中WAR文件是 Web Archive File,它对应一个Web应用文档;而EAR文件就是 Enterprise Archive File,它对应于一个企业应用文档(通常由Web应用和EJB两个部分组成)。实际上,WAR包和EAR包的压缩格式及压缩方式与JAR包完全一样,只是改变了文件后缀而已。