赞
踩
首先要明确的一点是 jar 包是压缩包,它可以使用 zip/unzip 命令解压,实际它是类 zip 的压缩文件。
jar 是随 JDK 安装的,在 JDK 安装目录下的 bin 目录中,Windows 下文件名为 jar.exe,Linux 下文件名为 jar。它的运行需要用到 JDK 安装目录下 lib 目录中的 tools.jar 文件。不过我们除了安装 JDK 什么也不需要做,因为 SUN 已经帮我们做好了。我们甚至不需要将 tools.jar 放到环境变量 CLASSPATH
中。
jar 包中有一个文件 META-INF\MANIFEST.MF
,当你生成 jar 包时,它会自动生成。
欲了解文件 META-INF\MANIFEST.MF
的详细内容,猛戳《Java 打 jar 包时,MANIFEST.MF 文件详解》
命令格式:jar {c t x u f } [ v m e 0 M i ] [-C 目录] <文件名...>
其中 {c t x u} 这四个选项必须选其一。[v f m e 0 M i ] 则是可选项,文件名也是必须的。
选项 | 说明 |
---|---|
-c | 创建一个 jar 包 |
-t | 显示 jar 中的内容列表 |
-x | 解压 jar 包,即展开 jar 文件包的指定文件或者所有文件 |
-u | 添加文件到 jar 包中,即更新已存在的 jar 文件包 |
-f | 指定jar包的文件名,通常这个选项是必须的 |
-v | 生成详细的报告并打印到标准输出 |
-m | 指定 MANIFEST.MF 文件,MANIFEST.MF 文件中可以对 jar 包及其中的内容作一些一设置 |
-M | 不产生 MANIFEST.MF ,此选项会忽略 -m 选项 |
-0 | 只打包,不压缩,这样产生的 jar 文件包会比不用该选项产生的文件包的体积大,但速度更快 |
-i | 为指定的jar文件创建索引文件 |
-C | 表示转到指定目录下去执行这个 jar 命令的操作。它相当于先使用 cd 命令切换到该目录下再执行不带 -C 参数的 jar 命令,它只能在创建和更新 jar 文件包的时候可用 |
jar-文件 | 指定需要生成、查看、更新或者解开的 jar 文件包,它是 -f 参数的附属参数 |
manifest-文件 | 指定 MANIFEST.MF 文件,它是 -m 参数的附属参数 |
文件名... | 指定一个文件或者目录列表,这些文件或者目录就是要添加到 jar 文件包中的文件或者目录。如果指定了目录,那么 jar 命令打包的时候会自动把该目录及目录中的所有文件和子目录打入包中 |
把目录 test 打包成 test.jar,并把 test.jar 放在当前目录下:
[root@linux ~]# jar -cf test.jar test
[root@linux ~]# jar cf test.jar test // 不要连接线"-",也行
把目录 test 打包成 test.jar,并把 test.jar 放在当前目录下,并显示打包信息:
[root@linux ~]# jar cvf test.jar test
使用了 M 选项,生成的 test.jar 中则不含有 META-INF/MANIFEST.MF 文件:
[root@linux ~]# jar cvfM test.jar test
使用 m 选项指定了 manifest.mf 文件:
[root@linux ~]# jar cvfm test.jar manifest.mf test
使用 t 选项可以查看 test.jar 中的内容:
[root@linux ~]# jar tvf test.jar # 在 test.jar
解开 test.jar 到当前目录:
[root@linux ~]# jar xf test.jar
将 HelloWorld.java 添加到 hello.jar 包中:
[root@linux ~]# jar uf hello.jar HelloWorld.java
在 test.jar 中添加了文件 manifest.mf,但是没有使用 -m 选项,所以此 manifest.mf 仅仅是一个普通文件。如果使用 -m 选项并指定 manifest.mf 文件,那么 manifest.mf 则作为清单文件来使用的:
[root@linux ~]# jar uf test.jar manifest.mf
[root@linux ~]# jar cvfm hello.jar mymanifest.mf -C hello/
使用选项 -i 会在 hello.jar 包的目录 META-INF 下生成一个名为 INDEX.LIST 的索引文件,它会生成一个列表,最上边为 jar 包名:
[root@linux ~]# jar i hello.jar
如果你想查看一个 jar 文件包内容列表,而这个 jar 包又很大,屏幕信息会一闪而过,这时你可以把列表输出到一个文件中,方便查看:
[root@linux ~]# jar tvf hello.jar > hello.txt
假设目录结构如下:
hello
|--- com
|--- org
你只想把 com 目录和 org 目录打包,而这时 jar -cvf hello.jar hello/*
命令会连同 hello
目录也一块打包。这点大家要注意。jar 命令生成的压缩文件会包含它后边出现的目录。不要含有 hello 目录,我们应该进入到 hello 目录再执行 jar 命令。
注意:manifest.mf 这个文件名,用户可以任意指定名称,但 jar 命令只认识 manifest.mf
,它会对用户指定的文件名进行相应在的转换,这不需用户担心。
jar 文件实际上就是 zip 文件,所以可以使用常见的一些解压 zip 文件的工具来解压 jar 文件,如 Windows 下的 Winzip、WinRAR 等和 Linux 下的 unzip 等。使用 Winzip 和 WinRAR 等来解压是因为它们解压比较直观,方便。而使用 unzip,则是因为它解压时可以使用 -d 参数指定目标目录。
在解压一个 jar 文件的时候是不能使用 jar 的 -C
参数来指定解压的目标目录的,因为 -C
选项只在创建或者更新包的时候可用。那么需要将文件解压到某个指定目录下的时候就需要先将 jar 文件拷贝到目标目录下,再进行解压,比较麻烦。如果使用 unzip,就不需要这么麻烦了,只需要指定一个 -d 选项即可。
将指定的 jar 包解压到指定的目录下:
[root@linux ~]# unzip test.jar -d dest/
实际上 jar 文件就是包含了 meta-inf/manifest.mf
的 zip 文件,所以,只需要使用 Winzip、WinRAR 等工具创建所需要的 zip 压缩包,再往这个 zip 压缩包中添加 meta-inf/manifest.mf
文件即可。
使用带 -M 参数的 jar 命令创建一个 jar 文件包,将.jar 扩展名改为 .zip 扩展名,创建的就是一个不折不扣的 zip 文件包。
使用命令 jar 将指定目录打包成一个 zip 压缩包:
[root@linux ~]# jar cvfM test.zip test
说明:-M 参数表示制作 jar 包的时候不添加文件 META-INF/MANIFEST.MF
。
java 文件内容如下:
public final class Person {
public static int getAge() {
return 30;
}
}
打开命令终端,编译和打包:
[root@linux ~]# javac Person.java # 编译源码文件
[root@linux ~]# jar cvf person.jar Person.class # 将字节码文件打包成 person.jar
再写一个类对其进行调用:
public class Test {
public static void main(String[] args) {
System.out.println(Person.getAge());
}
}
[root@linux ~]# javac Test.java // 编译源代码文件
[root@linux ~]# java -classpath person.jar:. Test // 执行二进制文件 Test
说明:
-classpath person.jar:.
是让 JVM 在当前目录下的 person.jar 或者当前目录下查找需要的 class 文件,多个路径之间使用冒号 :
分隔-classpath
,系统只会在指定的类路径中查找 Test.class,而在执行类 Test 中的 main 方法时,需要引用类 Person.class,也只会在指定的类路径中查找-classpath person.jar
就可以了,如果不在当前目录中,需要明确 jar 包的路径,假设 jar 包在当前目录下的子目录 test 中,则要写成 -classpath ./test/person.jar
如果 person.jar 和 Test.class 在同一个目录下,可以省略选项 -classpath
,因为没有选项 -classpath
的情况下,JVM 默认是在当前工作目录中查找类文件:
[root@linux ~]# java Test;
如果这样写,则会报错:
[root@linux ~]# java -classpath person.jar Test; # 提示类 Test 找不到,因为你指定在文件包 person.jar 中搜索类文件,而 person.jar 文件包中并没有文件 Test.class
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。