在jdk中,通过jar命令可以生成jar包,也可以解压一个jar包或war包。
一、jar命令
格式:jar {c t x u f }[ v m e 0 M i ][-C 目录]文件名...
其中,{ctxu}这四个参数必须选选其一;[v f m e 0 M i ]是可选参数,文件名也是必须的。
-c 创建一个jar包
-t 显示jar包中的内容列表
-x 解压jar包
-u 添加文件到jar包中
-f 指定jar包的文件名
-v 生成详细的报告,并输出至标准设备
-m 指定manifest.mf文件(用于对jar包及其中的内容进行设置)
-0 产生jar包时不对其中的内容进行压缩处理
-M 不产生所有文件的清单文件(manifest.mf),这个参数与忽略掉-m参数的设置相同
-i 为指定的jar文件创建索引文件
-C 表示转到相应的目录下执行jar命令,相当于首先cd到指定目录
二、jar使用范例
1、创建jar包
1
|
jar -cf hello.jar hello
|
利用hello目录生成hello.jar,若存在则覆盖之。
2、创建并显示打包过程
1
|
jar -cvf hello.jar hello
|
利用hello目录创建hello.jar,并显示创建过程:
D:\test>jar -cvf hello.jar hello
标明清单(manifest)
增加:hello/(读入= 0) (写出= 0)(存储了 0%)
3、显示jar包
1
2
3
4
5
6
7
8
9
10
11
|
jar -tvf hello.jar
D:\
test
>jar -cvf hello.jar hello
标明清单(manifest)
增加:hello/(读入= 0) (写出= 0)(存储了 0%)
D:\
test
>jar -tvf hello.jar
0 Mon May 06 12:37:10 CST 2013 META-INF/
71 Mon May 06 12:37:10 CST 2013 META-INF
/MANIFEST
.MF
0 Mon May 06 12:35:08 CST 2013 hello/
D:\
test
>
|
查看hello.jar的内容。指定的jar文件必须存在,否则会发生FileNotFoundException。
4、解压缩jar包
1
2
3
4
5
6
|
D:\
test
>jar xvf hello.jar
创建:META-INF/
解压 META-INF
/MANIFEST
.MF
创建:hello/
D:\
test
>
|
解压缩hello.jar至当前目录
5、向jar中添加文件
1
2
3
4
5
6
7
8
9
|
D:\
test
>jar uf hello.jar Hello.class
D:\
test
>jar tvf hello.jar
0 Mon May 06 12:37:10 CST 2013 META-INF/
71 Mon May 06 12:37:10 CST 2013 META-INF
/MANIFEST
.MF
0 Mon May 06 12:35:08 CST 2013 hello/
1480 Mon Jul 30 16:26:30 CST 2007 Hello.class
D:\
test
>
|
将Hello.class添加到hello.jar中。注意,是直接添加到hello.jar目录下。
6、创建不压缩内容的jar包
1
2
3
4
5
|
D:\
test
>jar cvf0 hello2.jar *.class
标明清单(manifest)
增加:Hello.class(读入= 1480) (写出= 1480)(存储了 0%)
D:\
test
>
|
利用当前目录中所有的.class文件生成一个不压缩的jar包。
7、使用已有的manifest.mf文件并创建jar包
1
2
3
4
5
|
D:\
test
>jar cvfm hello4.jar manifest.mf *.class
标明清单(manifest)
增加:Hello.class(读入= 1480) (写出= 801)(压缩了 45%)
D:\
test
>
|
使用已有的MANIFEST.MF文件,并将*.class文件打包为hell4.jar。
8、忽略manifest.mf文件
1
2
3
4
5
6
7
|
D:\
test
>jar cvfM hello5.jar *.class
增加:Hello.class(读入= 1480) (写出= 801)(压缩了 45%)
D:\
test
>jar tvf hello5.jar
1480 Mon Jul 30 16:26:30 CST 2007 Hello.class
D:\
test
>
|
生成的jar包中不包括META-INF目录及manifest.mf文件。
9、用-C 更改为指定的目录并包含其中的文件
1
2
3
4
5
6
7
8
|
D:\
test
>jar cvfm hello6.jar manifest.mf -C here/ .
标明清单(manifest)
D:\
test
>jar tvf hello6.jar
0 Mon May 06 13:18:58 CST 2013 META-INF/
72 Mon May 06 13:18:58 CST 2013 META-INF
/MANIFEST
.MF
D:\
test
>
|
10、用-i为jar文件生成索引列表
1
2
3
4
5
6
7
8
9
10
|
D:\
test
>jar i hello.jar
D:\
test
>jar tvf hello.jar
52 Mon May 06 13:22:30 CST 2013 META-INF
/INDEX
.LIST
0 Mon May 06 12:37:10 CST 2013 META-INF/
71 Mon May 06 12:37:10 CST 2013 META-INF
/MANIFEST
.MF
0 Mon May 06 12:35:08 CST 2013 hello/
1480 Mon Jul 30 16:26:30 CST 2007 Hello.class
D:\
test
>
|
对一个已经完成的jar包,通过jar i 为其生成一个索引文件。执行完本条命令后,会在hello.jar的META-INF文件夹下生成一个名为INDEX.LIST的索引文件。该文件记录了一个列表,包括jar包名、jar包下的目录和文件名。本例生成的INDEX.LIST内容为:
1
2
3
4
5
|
JarIndex-Version: 1.0
hello.jar
hello
Hello.class
|
11、导出解压列表
1
2
3
4
5
6
7
8
|
D:\
test
>jar tvf hello.jar >hello.txt
Hello.txt内容为:
52 Mon May 06 13:22:30 CST 2013 META-INF
/INDEX
.LIST
0 Mon May 06 12:37:10 CST 2013 META-INF/
71 Mon May 06 12:37:10 CST 2013 META-INF
/MANIFEST
.MF
0 Mon May 06 12:35:08 CST 2013 hello/
1480 Mon Jul 30 16:26:30 CST 2007 Hello.class
|
当要查看解压一个jar的详细过程,而这个jar又比较大时,屏幕信息会一闪而过,这时可以用>把列表输出到一个文件中,慢慢欣赏。
12、jar命令的目录问题
若目录here包括 com、org两个文件夹,若只想把com目录和org目录打成jar包,则应该先进入here目录,再执行jar命令。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
D:\
test
>jar cvf here1.jar here/*
标明清单(manifest)
增加:here
/com/
(读入= 0) (写出= 0)(存储了 0%)
增加:here
/org/
(读入= 0) (写出= 0)(存储了 0%)
D:\
test
>jar tvf here1.jar
0 Mon May 06 13:38:10 CST 2013 META-INF/
71 Mon May 06 13:38:10 CST 2013 META-INF
/MANIFEST
.MF
0 Mon May 06 13:34:26 CST 2013 here
/com/
0 Mon May 06 13:34:28 CST 2013 here
/org/
D:\
test
>
cd
here
D:\
test
\here>jar cvf here2.jar *
标明清单(manifest)
增加:com/(读入= 0) (写出= 0)(存储了 0%)
增加:org/(读入= 0) (写出= 0)(存储了 0%)
D:\
test
\here>jar tvf here2.jar
0 Mon May 06 13:39:08 CST 2013 META-INF/
71 Mon May 06 13:39:08 CST 2013 META-INF
/MANIFEST
.MF
0 Mon May 06 13:34:26 CST 2013 com/
0 Mon May 06 13:34:28 CST 2013 org/
|
比较here1.jar和here2.jar可以看出,here1.jar多了一层here目录。
三、Manifest.mf文件编写规范
manifest.mf的编写一定要注意如下细节:
1、不能有空行和空格的地方:第一行不能是空行( 第一行的行前不能有空行),行与行之间不能有空行,行尾不可以有空格。
2、一定要有空行的地方:最后一行得是空行(在输完你的内容后加一个回车就OK) 。
3、一定有空格的地方:
1
|
key: value
|
在分号后面一定要写写一个空格。例如:
1
2
3
|
Manifest-Version:
1.0
Ant-Version: Apache Ant
1.6
.
5
Created-By:
1.5
.0_06-b05 (Sun Microsystems Inc.)
|
四、Jar调用实例
1、调用jar中的类
新建一个Person.java,编译成Person.class,然后再打成jar包。
1
2
3
4
5
6
7
|
D:\
test
>javac Person.java
D:\
test
>jar cvf person.jar *.class
标明清单(manifest)
增加:Person.class(读入= 239) (写出= 184)(压缩了 23%)
D:\
test
>
|
再写一个类对其进行调用:
1
2
3
4
5
6
7
8
|
public
class
MyAge{
public
static
void
getAge(){
System.out.println(Person.age());
}
public
static
void
main(String[] args){
getAge();
}
}
|
此时,在test目录下有:Person.java, Person.class, person.jar, MyAge.java
然后,编译MyAge.java,生成 MyAge.class,执行java MyAge。注:通过指定classpath的方式执行class文件未成功。
2、创建可执行jar包
步骤:
1)、编辑manifest.mf文件,加入一行Main-Class,标识出主类:
Main-Class: MyApplet
2)、打包,
1
|
jar cvfm FirstApplet.jar manifest.mf MyApplet.class
|
3)、使用可执行jar文件
命令行:
1
|
java -jar FirstApplet.jar
|
在applet中使用:
1
2
|
<
applet
code
=
MyApplet
archive
=
FirstApplet
.jar
width
=
200
height
=
100
>
</
applet
>
|
3、扩展类说明
1)、在jdk的安装目录\jre\lib\ext目录下,可以将自己的类文件打成jar包放在此目录下,java由ExtClassLoader类装载器负责进行装载。
ExtClassLoader类装载器是AppClassLoader类装载器的父装载器,AppClassLoader主要负责加载CLASSPATH路径下的文件。
java中采用的是委托父类装载器的机制,\jre\lib\ext目录下的jar中的类文件不做任何设置,类装载器即可以找到并正常加载。
2)、对于applet使用的jar,可以在打包成jar包之前,在其manifest.mf中加入下面两行:
1
2
3
|
Class-Path: FirstApplet.jar
Class-Path: SecondApplet.jar
Main-Class: MyApplet
|
其中,Class-Path可以设置多项,直接写jar包全名即可。Main-Class主要用于当jar中有多个.class类文件时,为java指定哪个是主类。若jar包中只有1个类,可以不指定。
总结:Java调用类的顺序:java\lib\ext中的类 --> Manifest.MF中指定的类 --> 当前目录中的类 --> set CLASSPATH中指定的类。
3)、调用url网络上的jar包
1
2
3
4
5
6
7
8
9
10
|
URL u =
new
URL(
"jar:"
+
"FirstApplet.jar"
+!/");
//生成jar包的URL
JarURLConnection juc = (JarURLConnection)u.openConnection();
//建立jarURLConnection对象
Attributes attr = juc.getMainAttributes();
String name = attr.getValue(
"Main-Class"
);
//返回jar中主类的名字(要求在manifest.mf中已设置了Main-Class属性)
Class c = Class.forName(name);
//根据主类名创建class对象
Method cm = c.getMethod(
"main"
,
new
Class[]{String.
class
});
//根据Class对象调用其main方法,此处利用了Java reflection反射机制
cm.invoke(
null
,
new
Object[]{});
|
五、Jar命令其他相关内容
1、使用jar创建zip压缩文件
1
2
3
4
5
6
7
|
D:\
test
>jar cvfM testZip.jar here
增加:here/(读入= 0) (写出= 0)(存储了 0%)
增加:here
/com/
(读入= 0) (写出= 0)(存储了 0%)
增加:here
/here2
.jar(读入= 513) (写出= 234)(压缩了 54%)
增加:here
/org/
(读入= 0) (写出= 0)(存储了 0%)
D:\
test
>ren testZip.jar testZip.zip
|
先打成不带META-INF相关内容的jar包,然后将jar包重命名为zip类型的文件即可。
2、winRAR可以解压jar文件,也可以生成jar文件。jar文件与zip 文件的区别就是,jar中可能多了一个META-INF目录,META-INF目录下有一个manifest.mf文件。