前言
Jar包,是Java™ Archive的缩写,可以用这项技术把多个文件捆绑为一个文件,或者说,一种比较特殊的压缩技术。
Jar包提供了很多的好处:
- 安全性:可以对jar包进行数字签名。
- 减少下载时间:下载一个压缩包的速度肯定是比下载很多文件要快的多的。
- 压缩:减少存储空间的消耗。
- 扩展打包:扩展框架提供了一种向Java核心平台提供功能的方法。
- 密封:所有的文件都被打包到了一起,所以可以强制版本统一。
- 版本控制:jar包可以提供供应商和版本信息。
- 可移植性:处理jar包是java的核心功能。
本博文主要翻译自java官方的tutorials,主要有四个部分,分别是简单使用jar包、manifest文件、签名和认证、使用相关api。
使用JAR文件:基础知识
jar包本质上其实就是通过zip文件格式进行打包的,标准情况下,Java Archive Tool是作为JDK的一部分提供的,而在日常中,我们使用的是jar命令。
创建jar包
用于创建 JAR 文件的命令的基本格式为:
1 | jar cf jar-file input-file(s) |
此命令中使用的选项和参数是:
c选项表示你要 create (创建) 一个JAR文件。f选项表示你希望输出转到 file (文件) 而不是stdout。jar-file是你希望生成的 JAR 文件具有的名称。你可以使用任何文件名作为 JAR 文件。通常来说,JAR文件名的扩展名为.jar,但这不是必需的。input-file(s)参数是一个以空格为分隔的列表,包含了需要打包在 JAR 文件中的一个或多个文件。input-file(s)参数可以包含通配符*符号。如果是一个目录,则其中的内容会递归地加入到jar包中。
此命令将生成压缩的JAR文件并将其放在当前目录中。该命令还将为JAR存档生成默认清单文件。默认清单文件取名叫META-INF/MANIFEST.MF,里面只有最基本的JDK等信息。
除此之外,还可以有的选项是:
- 选项描述
v在构建 JAR 文件时,在stdout上生成 verbose (详细) 输出。详细输出告诉你添加到 JAR 文件中的每个文件的名称。 0(zero)表示你不希望压缩 JAR 文件。不压缩的话,最后打开的时候会比较快,因为不需要解压缩了,不过占用空间会比较大,看实际需要进行调整。M表示不应生成默认清单文件。m用于包括现有清单文件中的清单信息。使用此选项的格式为:jar cmf jar-file existing-manifest input-file(s)C用于在打包的时候修改对应的结构。
注意jar包会存储创建文件的时间,所以多次创建jar包会有所不同。但是最好不要根据这点来作为版本控制信息,而是应该使用清单文件。
查看jar包
查看JAR文件内容的命令的基本格式是:
1 | jar tf jar-file |
让我们看看这个命令中使用的选项和参数:
t选项表示你要查看 JAR 文件内容的 *table (表)*。f选项表示在命令行中指定了要查看其内容的 JAR 文件。jar-file参数是要查看其内容的 JAR 文件的路径和名称。
此命令将 JAR 文件的目录显示到 stdout。
你可以选择添加详细选项 v,以在输出中生成有关文件大小和上次修改日期的其他信息。
解压jar包
用于提取 JAR 文件内容的基本命令是:
1 | jar xf jar-file [archived-file(s)] |
让我们看看这个命令中的选项和参数:
x选项表示你要从 JAR 存档中 extract (提取) 文件。f选项表示要从中提取文件的 JAR file (文件) 是在命令行中指定的,而不是通过 stdin 指定的。jar-file参数是从中提取文件的 JAR 文件的文件名(或路径和文件名)。archived-file(s)是一个可选参数,由要从存档中提取的文件的空格分隔列表组成。如果此参数不存在,Jar 工具将提取存档中的所有文件。
注解,当解压缩的时候,解压出来如果和当前文件有同名的情况,会覆盖掉原来的文件。
更新jar包
没啥用,基本上重新打一个就行了…
JAR文件作为应用程序
你可以使用 Java 启动程序(java 命令)运行 JAR 打包的应用程序。基本命令是:
1 | java -jar jar-file |
-jar 标志告诉启动程序应用程序是以 JAR 文件格式打包的。你只能指定一个 JAR 文件,该文件必须包含所有特定于应用程序的代码。
在执行此命令之前,请确保运行时环境具有有关 JAR 文件中哪个类是应用程序入口点的信息。
要指示哪个类是应用程序的入口点,必须将 Main-Class 头添加到 JAR 文件的清单中。头采用以下形式:
1 | Main-Class: classname |
头的值 classname 是作为应用程序入口点的类的名称。
在清单文件中设置 Main-Class 时,可以从命令行运行应用程序:
1 | java -jar app.jar |
总结
jar包本质上就是一个压缩包,所以如果你很熟练tar命令,其实jar命令就是手到擒来的事情。
使用清单文件:基础知识
之前提到jar包的很多功能,比如电子签名、版本控制之类的,这些就是通过清单文件(manifest)文件来实现的。
默认清单
创建jar包的时候,如果没有指定清单,那么系统会自动创建一个叫META-INF/MANIFEST.MF的清单。在jar包中,有且仅能有一个清单文件,而且名字必须是这个。
修改清单文件
在创建jar包的时候,可以通过m选项自己指定一个清单文件。注意,你自己准备的清单文件(不用在意叫什么,最后都会被强制改名的),必须以新行或回车符结束,否则会出现无法解析最后一行的问题。具体的格式是这样子的:jar cfm jar-file manifest-addition input-file(s),注意m 和 f 选项的顺序必须与相应的参数相同。
c选项表示你要 create (创建) 一个 JAR 文件。m选项表示你要将现有文件中的信息合并到正在创建的 JAR 文件的清单文件中。f选项表示你希望输出转到 file (文件)(你正在创建的 JAR 文件)而不是标准输出。manifest-addition是现有文本文件的名称(或路径和名称),其内容要添加到 JAR 文件清单的内容中。jar-file是你希望生成的 JAR 文件具有的名称。input-file(s)参数是一个以空格分隔的列表,其中包含要放置在 JAR 文件中的一个或多个文件。
设置入口点
jar包中需要通过指定哪个启动程序,可以通过Main-Class: classname进行指定,这样通过java -jar xxx.jar就可以启动对应的类了。
将类添加到 JAR 文件的类路径中
简单来说就是一个jar包引用另外一个jar包中的文件,那么可以直接在其的清单文件中直接指定Class-Path: jar1-name jar2-name directory-name/jar3-name
设置包版本信息
你可能需要在 JAR 文件的清单中包含软件包版本信息。你使用清单中的以下头提供此信息:
| 头 | 定义 |
|---|---|
Name |
规范的名称。 |
Specification-Title |
规范的标题。 |
Specification-Version |
规范的版本。 |
Specification-Vendor |
规范的供应商。 |
Implementation-Title |
实现的标题。 |
Implementation-Version |
实现的内部版本号。 |
Implementation-Vendor |
实现的供应商。 |
不过大概是接触不到的。