关于Jar文件

几乎人人都知道jar文件是一个zip格式的压缩文件,但是java规范里面对于jar文件还有不少额外的设定,这些设定跟应用运行环境也有密切关系,开发运维人员平时可能都不太关注这些点,其实这些内容还是很应该了解了解。

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的进程,估计适合Applet这种需要下载和装载远程的class的场景。

    - xxx.SF              : 是本jar文件的签名。

    - xxx.DSA           : 跟签名相关,忘了具体干啥的了。

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

    jar文件“可执行”的意义在于:1、(在windows里)双击该文件可以运行启动应用;2、用命令行或者cmd/sh等脚本可以运行启动jar文件。

    用命令行启动的方式是:java -jar myapplication.jar

    设置方法是设置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>

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."

此外,有一些做法存在,只是很少有人用到:

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的话,则其相关的数量可以大大降低。各自优劣,不言自明。

posted @ 2010-09-05 16:47  长须飘飘  阅读(2005)  评论(1编辑  收藏  举报