Jar是在发布Java应用程序时用到的一种文件格式。
JAR是 Java Archive File的缩写,是 Java 的一种文档格式,可将多个文件合并为单个JAR归档文件,jar是个多用途的存档及压缩工具,它基于ZIP和ZLIB压缩格式。JAR 文件非常类似 ZIP 文件,准确的说,它就是 ZIP 文件。JAR 文件与 ZIP 文件唯一的区别就是在 JAR 文件的内容中,包含了一个 META-INF/MANIFEST.MF 文件,这个文件是在生成 JAR 文件的时候自动创建的,这里做一个实验:若在某个目录下有文件a.java和b.java,此时在该目录下运行jar
cf test.jar *.java,则会在该目录下生成test.jar文件,用winrar打开可以看到其中多出来了一个META-INF目录,且在该目录下有一个文件MANIFEST.MF。这验证了前面所说的情况。下面将说明为什么test.jar中会多出META-INF/MANIFEST.MF 文件。
jar 文件实际上是class 文件的ZIP压缩存档,也正是因为这个原因,jar文件本身并不能表达所包含应用程序的标签信息。为了要提供存档的标签信息,Manifest 因此得以出现。jar 文件指定了一个特定目录来存放标签信息:META-INF 目录,其中包含MANIFEST.MF文件,它包含了JAR文件的内容描述,并在运行时向JVM提供应用程序的信息。
利用eclipse导出可执行jar包和这个META-INF/MANIFEST.MF文件息息相关。这里分两种情况对META-INF/MANIFEST.MF 文件的作用加以说明。
第一种情况:应用程序没有引用除JDK之外的第三方jar包。这时只需要右击工程选择“Export...”菜单,然后选择导出为JAR file,指定存放目录和名称后,在“Customize the manifest file for the JAR file.”步骤里有一项非常重要的工作,那就是指定这个可运行jar的程序入口,也就是“Main class”,然后点击Finish即可。这里以本人工程为例,其目录结构如下:
其中test.java源码如下
package test; public class test { public static void main(String[] args) { System.out.println("No other jar files."); } }
生成的jar包名称为testRun.jar。在cmd窗口下运行结果如下:
用winrar打下testRun.jar,其中META-INF/MANIFEST.MF 文件内容如下:
Manifest-Version: 1.0 Main-Class: test.test
其中,Manifest-Version用来定义manifest文件的版本, Main-Class定义jar文件的入口类,该类必须是一个可执行的类,一旦定义了该属性即可通过 java -jar x.jar来运行该jar文件。
这里需要说明的是,在MANIFEST.MF文件有很多属性字段,因为上面的test工程比较简单,所以只用到了Manifest-Version和Main-Class两个字段。在下面将要介绍的情况中,则必须要用到Class-Path字段。
第二种情况:应用程序引用了除JDK意外的第三方jar包。这里新建两个工程testJar和testRun。其中testJar工程用于提供方法调用,testRun工程调用testJar工程中定义的方法。testJar工程目录如下:
testJar.java源码如下:
package testJar; public class testJar { public static void display(String para){ System.out.println("echo para " + para); } }
把testJar工程导出为普通jar包,名称为testJar.jar,加入到testRun工程后,testRun目录结构如下:
目录中多了Referenced Libraries结构,其中包含了引入的第三方testJar.jar包。TestRun.java源码如下:
package testRun; import testJar.testJar; public class TestRun { public static void main(String[] args) { // TODO Auto-generated method stub testJar.display("ggggg"); } }
和第一种情况中的打包方式一样,把testRun工程打包成testRunJar.jar,运行该jar包,结果如下:
解决方法如下:打开testRunJar.jar包,编辑META-INF/MANIFEST.MF 文件,添加Class-Path属性,修改结果如下:
Manifest-Version: 1.0 Main-Class: testRun.TestRun Class-Path: ./testJar.jar
其中Class-Path属性告诉类装载器使用该值路径来搜索并加载第三方类。
修改META-INF/MANIFEST.MF 文件后运行结果如下:
ps:META-INF/MANIFEST.MF 文件有很多属性字段,并且有自己的语法格式,网上有很多资源
例如:
http://blog.csdn.net/dw_java08/article/details/7786526
http://www.cnblogs.com/kentyshang/archive/2012/11/28/2793843.html
http://blog.csdn.net/zhifeiyu2008/article/details/8829637
http://blog.sina.com.cn/s/blog_9075354e0101kc37.html
http://blog.snsgou.com/post-605.html