在java中jar文件是一个zip格式的压缩文件,虽然属于zip格式的压缩文件,但是java规范里面对于jar文件还有不少额外的设定,作为一名java开发者,我们应该了解一下。

1、基本概念

我们可以对一个jar文件进行签名,而有的工具或者容器则可以认识或解析我们所设置的签名,从而给这个jar程序赋予相应的权限或者发现代码是否曾被修改过。
Package Sealing: 来自同一个package的class文件都必须来自同一个jar文件。这样做的目的是为了保持版本一致性和安全。
Package Versioning: jar文件可以包含关于Vendor和Version的信息。

2、META-INF目录

这个目录存放的都是一些meta数据。可括如下文件:
MANIFEST.MF:最常用的一个文件,定义扩展属性,如版本,类包依赖等。
INDEX.LIST:用jar命令-i参数可以生成该文件,用于让ClassLoader可以加快装载class到jvm,估计适合Applet这种需要下载和装载远程的class的场景。
xxx.SF: 是本jar文件的签名。
xxx.DSA: 跟签名相关。

3、jar文件可以设置为“可执行”文件。

jar文件“可执行”的意义在于:
(1)在windows里双击该文件可以运行启动应用;
设置方法是设置jar文件中的META-INF目录中的MANIFEST.MF文件。
加入一行:Main-Class: com.mypackage.MyMainClass 即可
也可以采用Ant来设置或者生成这句话。

<jar destfile="myapp.jar" basedir="classes">
<manifest>
<attribute name="Main-Class" value="com.mypackage.MyMainClass" />
</manifest>
</jar>

(2)用命令行或者cmd,sh等脚本可以运行启动jar文件。
用命令行启动的方式是:java -jar myapplication.jar

4、Package Sealing

可以在MANIFEST.MF文件中设定类似如下的内容:
Name: com/mypackage/
Sealed: true
那么,你的package(com.mypackage)的类就必须都来自这同一个jar文件,否则JVM就会抛出异常。

5、jar文件中可以设定对其他jar的依赖关系

如果jar的运行需要引用其他jar,那么可以在 MANIFEST.MF中设定或者列出其他的jar。
列举时需要列出具体位置和文件名,如果用相对路径,则始于此jar所在的目录起,如果用绝对路径,则在Unix/Linux路径下用/开头,在Windows中似乎得用file:///。然后再接着Windows的路径,如:

Class-Path: ./lib/log4j-1.2.11.jar 
 ../otherlib/otherfile.jar 
 /share/lib/somefile.jar 
 //上面是Unix/Linux绝对路径 
 file:///D:/mydemo/myapp/lib/log4j-1.2.11.jar 
 //上面是Windows绝对路径


如果有多个依赖,则用空格或者回车隔开都可以。
同样可以用Ant来设置。

<attribute name="Class-Path"  value="./lib/a.jar ./lib/b.jar" />

6、可以把其他类型的文件(非.class文件)放到jar文件中

常规的如.properties文件,.xml文件都是经常放配置信息的,这些文件都可以放到.jar文件中。其实可以放一些图片,音频等,并且同样可以在应用程序中读取到这些文件。当然,不要放太大的文件,以免影响性能。
读取这些文件的方法很简单,就是类似MyClass.class.getClassLoader().getResourceAsStream(“/myfiles/myfile.xml”)的写法即可拿到一个InputStream。

7、Package Versioning

可以在jar中放入版本信息,如:

Name: java/util/ 
 Specification-Title: “Java Utility Classes” 
 Specification-Version: “1.2” 
 Specification-Vendor: “Sun Microsystems, Inc.”. 
 Implementation-Title: “java.util” 
 Implementation-Version: “build57” 
 Implementation-Vendor: “Sun Microsystems, Inc.”

8、 引入jar的另外方法

a、把jar文件放到JRE的lib/ext目录下,将隐性地能够被你的应用所引用到,即不需要显式出现在CLASSPATH或者你的MANIFEST.MF中;
b、Java6开始允许使用通配符来设定CLASSPATH,如java -classpath .\lib* myapp.jar,这样的话,lib地下的n个jar文件自动加入到CLASSPATH中,而不需要一一列举了。可惜不能在MANIFEST.MF中使用通配符。
另外,在J2EE环境下,我们通常部署ear/war,这些部署文件中都有大量的应用代码(.class文件),J2EE没有限制和规定这些.class文件是否一定要打包成.jar文件,如war目录中,可以采用在WEB-INF/classes里面放置大量的.class文件,虽然逻辑上是一样的东西,但是运行态是不同的。如果不打包的话,系统进程(Java服务器,如WebLogic)会需要用多个IO操作来打开程序文件,使用多个文件句柄;如果是打包成.jar的话,则其相关的数量可以大大降低。各自优劣,不言自明。