6.12.1 jar命令详解
jar
是随JDK
自动安装的,在JDK
安装目录下的bin
目录中,Windows
下文件名为jar.exe
, Linux
下文件名为jar
查看jar帮助文档
在CMD中输入jar
,可以看到jar
命令的帮助文档.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| C:\Users\lan>jar 用法: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ... 选项: -c 创建新档案 -t 列出档案目录 -x 从档案中提取指定的 (或所有) 文件 -u 更新现有档案 -i 为指定的 jar 文件生成索引信息
-v 在标准输出中生成详细输出 -f 指定档案文件名 -m 包含指定清单文件中的清单信息 -n 创建新档案后执行 Pack200 规范化 -0 仅存储; 不使用任何 ZIP 压缩 -P 保留文件名中的前导 '/' (绝对路径) 和 ".." (父目录) 组件 -M 不创建条目的清单文件 -e 为捆绑到可执行 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/ .
|
1. 创建JAR
文件
命令:jar cf test.jar -C dist/ .
1 2 3 4
| -c 创建新档案 -f 指定档案文件名
-C 更改为指定的目录并包含以下文件
|
将当前路径下的dist
路径下的全部内容生成一个test.jar
文件。如果当前目录中已经存在test.jar
文件,那么该test.jar
文件将被覆盖。
2. 创建JAR
文件 并显示压缩过程
命令:jar cvf test.jar -C dist/ .
1 2 3 4 5
| -c 创建新档案 -v 在标准输出中生成详细输出 -f 指定档案文件名
-C 更改为指定的目录并包含以下文件
|
1 2 3 4 5
| G:\Desktop\随书源码\疯狂Java讲义(第4版)光盘\codes\06\6.12>jar cvf test.jar -C dist/ . 已添加清单 正在添加: test/(输入 = 0) (输出 = 0)(存储了 0%) 正在添加: test/Test.class(输入 = 419) (输出 = 291)(压缩了 30%) 正在添加: test/Test.java(输入 = 421) (输出 = 320)(压缩了 23%)
|
3. 不使用清单文件
命令:jar cvfM test.jar -C dist/ .
1 2 3 4 5 6
| -c 创建新档案 -v 在标准输出中生成详细输出 -f 指定档案文件名 -M 不创建条目的清单文件
-C 更改为指定的目录并包含以下文件
|
1 2 3 4
| G:\Desktop\随书源码\疯狂Java讲义(第4版)光盘\codes\06\6.12>jar cvfM test.jar -C dist/ . 正在添加: test/(输入 = 0) (输出 = 0)(存储了 0%) 正在添加: test/Test.class(输入 = 419) (输出 = 291)(压缩了 30%) 正在添加: test/Test.java(输入 = 130) (输出 = 118)(压缩了 9%)
|
该命令的结果与第2个命令类似,其中M
选项表明不生成清单文件。因此生成的test.jar
中没有包含清单文件(META-INF/MANIFEST.MF
),打包过程的信息也略有差别。
4. 自定义清单文件内容
命令格式:jar cvfm JAR保存路径 清单文件路径 -C 目录 文件
运行结果与第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 -C dist/ .
实例
目录结构
1 2 3 4 5 6 7 8 9 10 11
| G:\Desktop\随书源码\疯狂Java讲义(第4版)光盘\codes\06\6.12 ├─a.txt ├─dist\ │ └─test\ │ ├─Test.class │ └─Test.java ├─dist7\ │ └─test\ │ ├─Test.class │ └─Test.java └─test.jar
|
a.txt
文件内容:
1 2
| G:\Desktop\随书源码\疯狂Java讲义(第4版)光盘\codes\06\6.12>type a.txt Hello: HelloWorld
|
将a.txt
中的内容添加到清单文件中:
1 2 3 4 5 6 7
| G:\Desktop\随书源码\疯狂Java讲义(第4版)光盘\codes\06\6.12>jar cvfm test.jar a.txt -C dist/ . 已添加清单 正在添加: test/(输入 = 0) (输出 = 0)(存储了 0%) 正在添加: test/Test.class(输入 = 419) (输出 = 291)(压缩了 30%) 正在添加: test/Test.java(输入 = 130) (输出 = 118)(压缩了 9%)
G:\Desktop\随书源码\疯狂Java讲义(第4版)光盘\codes\06\6.12>
|
生成的清单文件内容:
1 2 3
| Manifest-Version: 1.0 Hello: HelloWorld Created-By: 1.8.0_131 (Oracle Corporation)
|
5. 查看JAR包内容
命令:jar tf test.jar
1 2 3 4 5 6
| G:\Desktop\随书源码\疯狂Java讲义(第4版)光盘\codes\06\6.12>jar tf test.jar META-INF/ META-INF/MANIFEST.MF test/ test/Test.class test/Test.java
|
当JAR
包中的文件路径和文件非常多时,因为命令行窗口能显示的行数有限,所以直接执行该命令,可能无法看到包的全部内容,此时可利用重定向将显示结果保存到文件中。例如,采用如下命令:jar tf test.jar > test.txt
1 2 3 4 5 6 7 8
| G:\Desktop\随书源码\疯狂Java讲义(第4版)光盘\codes\06\6.12>jar tf test.jar > test.txt
G:\Desktop\随书源码\疯狂Java讲义(第4版)光盘\codes\06\6.12>type test.txt META-INF/ META-INF/MANIFEST.MF test/ test/Test.class test/Test.java
|
6. 查看JAR
包详细内容
命令:jar tvf test.jar
1 2 3 4 5 6
| G:\Desktop\随书源码\疯狂Java讲义(第4版)光盘\codes\06\6.12>jar tvf test.jar 0 Sun Sep 29 16:36:50 CST 2019 META-INF/ 88 Sun Sep 29 16:36:50 CST 2019 META-INF/MANIFEST.MF 0 Sat Sep 28 23:11:18 CST 2019 test/ 419 Sat Sep 28 23:11:18 CST 2019 test/Test.class 130 Sat Sep 28 23:10:28 CST 2019 test/Test.java
|
7. 解压缩
命令:jar xf test.jar
,这个命令会解压到当前目录下。
1 2
| -x 从档案中提取指定的 (或所有) 文件 -f 指定档案文件名
|
示例
jar xf JAR包
默认解压在当前路径下,为了观察明显,先把test.jar复制到其他地方.
1 2
| G:\Desktop\随书源码\疯狂Java讲义(第4版)光盘\codes\06\6.12>copy test.jar Copy 已复制 1 个文件。
|
然后再解压
1 2
| G:\Desktop\随书源码\疯狂Java讲义(第4版)光盘\codes\06\6.12>cd Copy G:\Desktop\随书源码\疯狂Java讲义(第4版)光盘\codes\06\6.12\Copy>jar xf test.jar
|
解压后的效果如下:
1 2 3 4 5 6 7 8
| G:\Desktop\随书源码\疯狂Java讲义(第4版)光盘\codes\06\6.12\Copy>mytree f G:\Desktop\随书源码\疯狂Java讲义(第4版)光盘\codes\06\6.12\Copy ├─META-INF\ │ └─MANIFEST.MF ├─test\ │ ├─Test.class │ └─Test.java └─test.jar
|
8. 带提示信息解压缩
命令:jar xvf test.jar
这个命令的解压缩效果与第7个命令相同,但系统会显示解压过程的详细信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| G:\Desktop\随书源码\疯狂Java讲义(第4版)光盘\codes\06\6.12\Copy>jar xvf test.jar 已创建: META-INF/ 已解压: META-INF/MANIFEST.MF 已创建: test/ 已解压: test/Test.class 已解压: test/Test.java
G:\Desktop\随书源码\疯狂Java讲义(第4版)光盘\codes\06\6.12\Copy>mytree f G:\Desktop\随书源码\疯狂Java讲义(第4版)光盘\codes\06\6.12\Copy ├─META-INF\ │ └─MANIFEST.MF ├─test\ │ ├─Test.class │ └─Test.java └─test.jar
|
9. 更新JAR文件
命令:jar uf test.jar Hello.class
,这个命令会更新test.jar
中的Hello.class
文件。如果test.jar
中已有Hello.class
件,则使用新的Hello.class
文件替换原来的Hello.class
文件;如果test.jar
中没有Helo.class
文件,则把新的Hello.class
文件添加到test.jar
文件中。
10.更新时显示详细信息
命令:jar uvf test.jar Hello.class
1.11 创建多版本JAR包
多版本JAR
包是JDK9
新增的功能,它允许在同一个JAR
包中包含针对多个Java
版本的cass
文件。JDK9
为jar
命令增加了一个 --release
选项,用于创建多版本JAR
包,注意,只有Java9
之后才支持多版本JAR
包。
如何使用指定版本的Java进行编译
在使用多版本JAR
包之前,可以使用Javac
的--release
选项针对指定Java
版本进行编译。比如命令:
javac --release 7 Test java
上面命令代表使用Java7
的语法来编译Test java
。如果你的Test java
中使用了Java8
或Java9
的语法,程序将会编译失败。
如果创建多版本JAR包
假如将针对Java7
编译的所有class
文件放在dist7
目录下,针对Java9
编译的所有class
文件放在dist
目录下。接下来可用如下命令来创建多版本JAR
包:
jar cvf test.jar -C dist7/ . --release 9 -C dist/ .
特定版本在JAR包中的位置
这样就创建了一个多版本JAR
包,在该多版本JAR
包内,特定版本的文件位于META-INF/versions/N
目录下,其中N
代表版本号。