java 清单文件
版权声明:本文为博主原创文章,未经博主允许不得转载。
1、jar简介
Java归档文件格式(JavaArchive, JAR)能够将多个源码、资源等文件打包到一个归档文件中。这样,有如下好处:
- 安全性
可以对整个jar包的内容进行签名。 - 减少了下载时间
如果applet被打包成一个jar文件,那么所有相关的资源就可以在一个HTTP transaction中下载完成,而无需为每一个文件新建一个连接。 - 压缩
减少了磁盘空间的占用。 - 容易扩展
通过jar这种格式,可以和容易地将自己的程序打包提供给别人使用。 - 包密封(Package Sealing)
存储在jar文件中的包可以被密封,来保证版本的一致性。密封可以保证一个包中的所有类都来自同一个jar文件。 - 包版本说明
一个jar包可以存储关于其内容的信息,包括提供商、版本等。 - 可移植性
处理jar文件的机制是Java平台核心API的标准模块。
From docs.oracle.com
2、jar的使用
JDK自带的打包工具通过jar
命令来调用,jar是通过zip格式进行打包的。所以,这个jar工具也可以作为日常的压缩、解压缩工具来进行使用。
2.1 jar命令说明
如果安装了JDK并配置了环境变量,在命令行中输入jar
命令,不加任何参数,就可以看到jar命令的使用说明,最下面还包含了两个例子:
jar
用法: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...
选项:
-c 创建新档案
-t 列出档案目录
-x 从档案中提取指定的 (或所有) 文件
-u 更新现有档案
-v 在标准输出中生成详细输出
-f 指定档案文件名
-m 包含指定清单文件中的清单信息
-n 创建新档案后执行 Pack200 规范化
-e 为捆绑到可执行 jar 文件的独立应用程序指定应用程序入口点
-0 仅存储; 不使用任何 ZIP 压缩
-P 保留文件名中的前导 '/' (绝对路径) 和 ".." (父目录) 组件
-M 不创建条目的清单文件
-i 为指定的 jar 文件生成索引信息
-C 更改为指定的目录并包含以下文件
如果任何文件为目录, 则对其进行递归处理。
清单文件名, 档案文件名和入口点名称的指定顺序与 'm', 'f' 和 'e' 标记的指定顺序相同。
示例 1: 将两个类文件归档到一个名为 classes.jar 的档案中:
jar cvf classes.jar Foo.class Bar.class
示例 2: 使用现有的清单文件 'mymanifest' 并将 foo/ 目录中的所有文件归档到 'classes.jar' 中:
jar cvfm classes.jar mymanifest -C foo/
摘自<jar命令的帮助文档>
2.2 jar使用举例
jar命令打包时默认会在jar包中添加清单(manifest)文件,如果不想添加,手动指定-M
选项:
>jar -cvf HelloWorld.jar HelloWorld.class #将HelloWorld.class文件打入jar包
已添加清单
正在添加: HelloWorld.class(输入 = 427) (输出 = 289)(压缩了 32%)
>jar -tf HelloWorld.jar #查看归档文件的内容
META-INF/
META-INF/MANIFEST.MF
HelloWorld.class
>jar -xf HelloWorld.jar META-INF/MANIFEST.MF #解压出其中的META-INF/MANIFEST.MF文件
>type META-INF\MANIFEST.MF #查看清单文件的内容
Manifest-Version: 1.0
Created-By: 1.8.0_51 (Oracle Corporation)
>jar -cvfM HelloWorld.jar HelloWorld.class #将HelloWorld.class文件打入jar包,不要添加清单文件
正在添加: HelloWorld.class(输入 = 427) (输出 = 289)(压缩了 32%)
>jar -tf HelloWorld.jar
HelloWorld.class
>jar -xf HelloWorld.jar #解压tar文件到当前目录
如果要生成可以运行的jar包,需要指定jar包的应用程序入口点,用-e选项:
>jar -cvfe HelloWorld.jar HelloWorld HelloWorld.class #创建可以运行的jar包
已添加清单
正在添加: HelloWorld.class(输入 = 427) (输出 = 289)(压缩了 32%)
>jar -tf HelloWorld.jar #查看归档的内容
META-INF/
META-INF/MANIFEST.MF
HelloWorld.class
>type META-INF\MANIFEST.MF #查看清单文件的内容
Manifest-Version: 1.0
Created-By: 1.8.0_51 (Oracle Corporation)
Main-Class: HelloWorld
>java -jar HelloWorld.jar #运行jar包
Hello World!!
3、清单文件MANIFEST.MF
jar打包时,会默认向jar包中添加一个清单文件(MANIFEST.MF),放在META-INF目录。上面的例子中,可以看到:如果指定了jar包的入口程序,清单文件中就会多一行Main-Class: HelloWorld
。实际上,-e
选项的作用就是向MANIFEST.MF文件中添加这样一行信息,来声明jar包的入口程序。当然,我们也可以直接修改清单文件的内容。
3.1 修改清单文件的内容
前面已经说了,-m
选项可以添加指定清单文件中的清单信息,格式如下:
jar cfm jar-file manifest-addition input-file(s)
注意:
- manifest-addition是一个已经存在的文本文件,其中包含着想要往jar包的清单文件中添加的清单信息。
- manifest-addition的文件编码格式必须是UTF-8。
- 清单信息每行后面必须有回车或者换行。(The text file from which you are creating the manifest must end with a new line or carriage return. The last line will not be parsed properly if it does not end with a new line or carriage return.)
- 清单文件名, 档案文件名和入口点名称的指定顺序与 ‘m’, ‘f’ 和 ‘e’ 标记的指定顺序相同。(前面已经提到了)
3.2 在清单文件中声明入口程序
>type manifest.txt #查看清单信息的内容
Main-Class: HelloWorld
>jar -cvfm HelloWorld.jar manifest.txt HelloWorld.class #添加清单信息到jar包
已添加清单
正在添加: HelloWorld.class(输入 = 427) (输出 = 289)(压缩了 32%)
>jar -xvf HelloWorld.jar META-INF\MANIFEST.MF
已解压: META-INF/MANIFEST.MF
>type META-INF\MANIFEST.MF
Manifest-Version: 1.0
Created-By: 1.8.0_51 (Oracle Corporation)
Main-Class: HelloWorld #可以看到清单信息成功添加
>java -jar HelloWorld.jar #这样指定入口程序,生成的jar包照样可以运行。
Hello World!!
3.3 在清单文件中指定CLASSPATH
在运行java
命令的时候,如果指定了-jar
选项,那么环境变量CLASSPATH和在命令行中指定的所有类路径都被JVM所忽略。这时,如果一个jar包引用了其它的jar包,解决方案有两个:
java -cp lib\log4j-1.2.14.jar;hello.jar com.dhn.Hello
(com.dhn.Hello为主类)
在windows下多个jar之间以分号(;)隔开,最后还需要指定运行jar文件中的完整的主类名。java -jar hello.jar
这种,需要修改hello.jar中的MANIFEST.MF,通过MANIFEST.MF中的Class-Path 来指定运行时需要用到的其他jar,其他jar可以是当前路径也可以是当前路径下的子目录。多个jar文件之间以空格隔开。
以下面的MANIFEST.MF文件为例Manifest-Version: 1.0
Main-Class: com.ibm.portalnews.entrance.Main
Class-Path: lib\commons-collections-3.2.jar lib\commons-configuration-1.5.jar lib\commons-lang-2.3.jar lib\commons-logging.jar lib\dom4j-1.6.1.jar lib\jaxen-1.1-beta-7.jar lib\jdom.jar lib\log4j-1.2.14.jar
其中:
- Manifest-Version表示版本号,一般由IDE工具(如eclipse)自动生成
- Main-Class 是jar文件的主类,程序的入口
- Class-Path 指定需要的jar,多个jar必须要在一行上,多个jar之间以空格隔开,如果引用的jar在当前目录的子目录下,windows下使用\来分割,linux下用/分割
- 文件的冒号后面必须要空一个空格,否则会出错
- 文件的最后一行必须是一个回车换行符,否则也会出错
From: java -jar classpath心得
3.4 将jar包A引用的其它jar包一同打包到A里面
这个问题,是我一直想的。如果这样,那么将一个程序到处拷贝的话就方便的多了。然而,这是行不通的,因为JDK的类加载器不会加载jar包内包含的其它jar包中的类。
当然,这样想过的人不止我一个,可以通过一些第三方的工具来完成。比如有个工具叫one-jar,感兴趣的可以看下。
3.5 通过清单文件密封包
JAR中的Package Sealing功能是在java1.2引入的。在生成Jar文件时我们可以指定是否将整个Jar或者其中某几个Package进行密封,如果是将Jar文件整个进行密封,那就意味着其内所有的Package都被密封了。Package一旦密封,那么Java 虚拟机一旦成功装载密封Package中的某个类后,其后所有装载的带有相同Package名的类必须来自同一个Jar文件,否则将触发Sealing Violation安全异常。
对包的密封方式主要有两种:一种是对jar文件中的某些包进行密封,另一种是密封jar中的所有包。
对某些包密封。
Manifest-Version: 1.0
Created-By: 1.8.0_51 (Oracle Corporation) Name: com/test/hello/
Sealed: true
Name: com/test/world/
Sealed: true
密封jar中的所有包。
Manifest-Version: 1.0
Created-By: 1.8.0_51 (Oracle Corporation)
Sealed: true
概括来说,有两种情况触发关于Sealing的安全异常:
1. 检查当前试图加载的类对应的Package是否已经被JVM装载且密封。如果已经被装载且密封了,但被密封的Package与当前加载的类对应的Package不是来自同一个Jar文件,将触发安全异常。
2. 检查当前试图加载的类对应的 Package是否已经被JVM装载且密封。如果已经被装载但没有被密封,但当前试图加载的类对应的Package确要试图进行密封操作,将触发安全异常。JVM不允许对已经装载但未密封的Package再进行密封操作。Package Sealing的好处:
Package Sealing所能带来的好处主要是版本一致性. 我们知道Java 在运行时是严格按照classpath中定义的顺序进行装载和检查,尤其是现在Java开源包满天飞, 很有可能你的Java应用程序或者中间件的classpath中会在不同的Jar文件中包含同一个Package的不同版本。这会使得程序运行产生不一致性结果,很难发现。
java 清单文件的更多相关文章
- Android(java)学习笔记217:开发一个多界面的应用程序之清单文件
清单文件的重要参数: <intent-filter> 代表的应用程序的入口界面 <action android:name=&quo ...
- Android(java)学习笔记160:开发一个多界面的应用程序之清单文件
清单文件的重要参数: <intent-filter> 代表的应用程序的入口界面 <action android:name=&quo ...
- demo工程的清单文件及activity中api代码简单示例
第一步注册一个账户,并创建一个应用.获取app ID与 app Key. 第二步下载sdk 第三步新建工程,修改清单文件,导入相关的sdk文件及调用相应的api搞定. 3.1 修改清单文件,主要是加入 ...
- Android清单文件详解(三)----应用程序的根节点<application>
<application>节点是AndroidManifest.xml文件中必须持有的一个节点,它包含在<manifest>节点下.通过<application>节 ...
- Android AndroidManifest 清单文件以及权限具体解释
每一个Android应用都须要一个名为AndroidManifest.xml的程序清单文件,这个清单文件名称是固定的而且放在每一个Android应用的根文件夹下.它定义了该应用对于Android系统来 ...
- Android AndroidManifest 清单文件以及权限详解!【转】
转自:http://my.oschina.net/yuanxulong/blog/366753 每个Android应用都需要一个名为AndroidManifest.xml的程序清单文件,这个清单文件名 ...
- [android]清单文件中MAIN与LAUNCHER的区别
原文:[android]清单文件中MAIN与LAUNCHER的区别 MAIN 和 LAUNCHER,之前一直不注意这两个有区别,写程序的时候都放到一个filter中,前两天面试问到了,总结一下: MA ...
- Android清单文件具体解释(三)----应用程序的根节点<application>
<application>节点是AndroidManifest.xml文件里必须持有的一个节点,它包括在<manifest>节点下.通过<application>节 ...
- Android基础知识点-Manifest清单文件
每个应用的根目录中都必须包含一个 AndroidManifest.xml 文件(且文件名精确无误). 清单文件向 Android 系统提供应用的必要信息,系统必须具有这些信息方可运行应用的任何代码. ...
随机推荐
- 利用yii2分页插件,成对取出数组数据
数组太大不好处理,切割出来处理 $ids = [1, 2, 3, 4, 5, 6, 7, 8, 9]; $count = count($ids);$size = 2; $pages = new Pag ...
- bzoj 3594
题解见: http://blog.csdn.net/qpswwww/article/details/44407371 收获: 1.对于一个问题,看似不可做,但一定存在一定特点,我们要做的就是找出一些特 ...
- Ext.js 中 25种类型的Ext.panel.Tool
通过Ext.panel.Panel的tools配置项来设置Ext.panel.Tool实例. 要注意的一点是,Ext框架提供的Ext.panel.Tool仅包含按钮图标而具体的点击事件处理函数需要我们 ...
- LwIP buffer management, memory configuration options
http://www.st.com/st-web-ui/static/active/cn/resource/technical/document/application_note/DM00036052 ...
- Spring AOP通知实例 – Advice
Spring AOP(面向方面编程)框架,用于在模块化方面的横切关注点.简单得说,它只是一个拦截器拦截一些过程,例如,当一个方法执行,Spring AOP 可以劫持一个执行的方法,在方法执行之前或之后 ...
- DiscuzX2.5 程序底层架构
程序底层架构 • 要求PHP版本大于5.1,抛弃了对PHP4的支持 • 大量使用了面向对象编程(OOP) • 实现了程序运程过程中按需加载,按需加载主要是针对类文件 • 对目录名.文件名和类名的要求 ...
- 《UNIX环境高级编程》笔记--errno是否是线程安全的?
当UNIX函数出错时,常常返回一个负数,而且整形变量errno通常被设置为含有附加信息的一个值,例如,open函数如成功,返回 一个非负文件描述符,如果出错就返回-1,在open出错时,有大约15种不 ...
- spingBoot-自定义过滤器
package com.cx.springboot.filters; import java.io.IOException; import javax.servlet.Filter; import j ...
- node.js&pm2搭建node生产环境
node.js下载地址https://nodejs.org/en/download/stable/ 下载截图 建议采用稳定编译过的版本,source code稍麻烦,编译过的直接可用,安装超级简单,红 ...
- Java:使用 Java 开发的一个异常处理框架
背景 这篇文章介绍的异常处理思路不错,本文试图给出一种具体实现,当然可能和作者的思路有所不同. 框架地址:https://github.com/happyframework/HappyFramewor ...