Jar命令 Manifest.mf的用法

本文介绍了如何使用jar命令创建JAR文件,并深入探讨了Manifest文件的用途与配置方法,包括主类指定、依赖管理及包版本声明等内容。

1.在命令行中输入“jar -help”,就k可看到jar的详细用法了。

2.示例:

   1)将两个class文档归档到一个jar文件中:jar -cvf  XX.jar  A.class B.class

   2 )使用清单文件Manifest.mf将dir目录下的所有文件归档到一个jar中:jar -cvfm   XX.jar  Manifest.mf dir/*

      manifest 文件的格式很简单,每一行都是  " 名-值 "  对应的:

      属性名开头,接着是 ":" ,然后是属性值,每行最多72个字符,如果需要增加,你可以在下一行续行,续行以空格开头,以空格开头的行       都会被视为前一行的续行。 
      使用 m 选项,把指定文件名的manifest文件传入,例如 
      jar cvfm myapplication.jar myapplication.mf [-C]classdir

Manifest.mf的详细用法(转)

现在我们来体验一下manifest文件的作用,如果现在我们有一个Java 应用程序打包在myapplication.jar中, main class为 com.example.myapp.MyAppMain ,那么我们可以用以下的命令来运行 
java -classpath myapplication.jar com.example.myapp.MyAppMain
这显然太麻烦了,现在我们来创建自己的manifest文件,如下:
Manifest-Version: 1.0
Created-By: JDJ example
Main-Class: com.example.myapp.MyAppMain
这样我们就可以使用如下的命令来运行程序了:(明显简单多了,也不会造成无谓的拼写错误)
java -jar myapplication.jar


管理JAR的依赖资源
很少Java应用会仅仅只有一个jar文 件,一般还需要 其他类库。比如我的应用程序用到了Sun 的 Javamail classes ,在classpath中我需要包含activation.jar 和 mail.jar,这样在运行程序时,相比上面的例子,我们要增加一些:
java -classpath mail.jar:activation.jar -jar myapplication.jar
在不同的操作系统中,jar包间的分隔符也不一样,在UNIX用“:”,在 window中使用 “;”,这样也不方便
同样,我们改写我们的manifest文件,如下
Manifest-Version: 1.0
Created-By: JDJ example
Main-Class: com.example.myapp.MyAppMain
Class-Path: mail.jar activation.jar
(加入了Class-Path: mail.jar activation.jar,用空格分隔两个jar包)
这样我们仍然可以使用和上例中相同的命令来执行该程序:
java -jar myapplication.jar
Class-Path属性中包含了用空格分隔的jar文件,在这些jar文件名中要对特定的字符使用逃逸符,比如空格,要表示成"%20",在路径的表示中,都采用“/” 来分隔目录(),无论是在什么操作系统中,(即使在window中),而且这里用的是相对路径(相对于本身的JAR文 件): 
Manifest-Version: 1.0
Created-By: JDJ example
Main-Class: com.example.myapp.MyAppMain
Class-Path: ext/mail.jar ext/activation.jar


Multiple Main Classes(多主类)
还有一种Multiple Main Classes情况,如果你的应用程序可能有命令行版本 和GUI版本,或者一些不同的应用却共享很多相同的代码,这时你可能有多个Main Class,我们建议你采取这样的策略:把共享的类打成lib包,然后把不同的应用打成不同的包,分别标志主类:如下
Manifest for myapplicationlib.jar:
Manifest-Version: 1.0
Created-By: JDJ example
Class-Path: mail.jar activation.jar

Manifest for myappconsole.jar:
Manifest-Version: 1.0
Created-By: JDJ example
Class-Path: myapplicationlib.jar
Main-Class: com.example.myapp.MyAppMain

Manifest for myappadmin.jar:
Manifest-Version: 1.0
Created-By: JDJ example
Class-Path: myapplicationlib.jar
Main-Class: com.example.myapp.MyAdminTool
在myappconsole.jar 和 myappadmin.jar的manifest文件中分别注明各自的 Main Class
Package Versioning
完成发布后,如果使用者想了解 ,哪些代码是谁的?目前是什么版本?使用什么版本的类库?解决的方法很多 ,manifest提供了一个较好的方法,你可以在manifest文件中描述每一个包的信息。


Java 秉承了实现说明与描述分离的原则,package 的描述 定义了package 是什么,实现说明 定义了谁提供了描述的实现,描述和实现包含 名、版本号和提供者。要得到这些信息,可以查看JVM的系统属性(使用 java.lang.System.getProperty() )
在manifest文件中,我可以为每个package定义描述和实现版本,声明名字,并加入描述属性和实现属性,这些属性是
Specification-Title
Specification-Version
Specification-Vendor
Implementation-Title
Implementation-Version
Implementation-Vendor
当要提供一个类库或编程接口时,描述信息显得是很重要,见以下范例:
Manifest-Version: 1.0
Created-By: JDJ example
Class-Path: mail.jar activation.jar
Name: com/example/myapp/
Specification-Title: MyApp
Specification-Version: 2.4
Specification-Vendor: example.com
Implementation-Title: com.example.myapp
Implementation-Version: 2002-03-05-A
Implementation-Vendor: example.com
Package Version 查询
在manifest文件中加入package描述后,就可以使用Java提供的java.lang.Package class进行Package 的信息查询,这里列举3个最基本的获取package object的方法
1.Package.getPackages():返回系统中所有定义的package列表
2.Package.getPackage(String packagename):按名返回package
3.Class.getPackage():返回给定class所在的package
使用者这方法就可以动态的获取package信息.
需要注意的是如果给定的package中没有class被加载,则也无法获得package 对象

 

Manifest 技巧
总是以Manifest-Version属性开头
每行最长72个字符,如果超过的化,采用续行
确认每行都以回车结束,否则改行将会被忽略
如果Class-Path 中的存在路径,使用"/"分隔目录,与平台无关
使用空行分隔主属性和package属性
使用"/"而不是"."来分隔package 和class ,比如 com/example/myapp/
class 要以.class结尾,package 要以 / 结尾

 

<think>我们被要求介绍jar包的MANIFEST.MF文件的内容。根据引用[1]和[2],MANIFEST.MFJAR包中必须的文件,位于META-INF目录下,它记录了程序的主要属性,如主类声明、版本信息、依赖库等。 引用[1]提到:MANIFEST.MF文件对于JAR文件是必不可少的,它记录了程序的主要属性,如主类声明、版本信息、依赖库等关键信息。 引用[2]进一步说明:MANIFEST.MF文件是jar文件运行依赖的入口,配置不正确会导致部署失败。 引用[3]给出了一个具体问题:如果没有指定Main-Class属性,运行jar包时会报“没有主清单属性”的错误,并指出在Idea打包时,MANIFEST.MF文件的位置需要正确设置。 引用[4]提到了在Maven项目中引入本地jar包并生成jar包时修改MANIFEST.MF文件。 引用[5]则展示了一个MANIFEST.MF文件的例子,其中包含了Manifest-Version, Main-Class, Class-Path等属性。 因此,我们可以将MANIFEST.MF文件的内容分为几个关键部分进行介绍: 1. 基本属性: - Manifest-Version: 指定清单文件的版本,通常是1.0。 - Created-By: 生成该JAR包的工具和版本,例如Apache Maven 3.8.1。 2. 主类入口(可执行的JAR必需): - Main-Class: 指定程序的入口点,即包含main方法的全限定类名。例如:`Main-Class: com.example.Main` 3. 类路径(Class-Path): - Class-Path: 指定运行该JAR包时所需的其他库文件(JAR包)或目录。路径之间用空格分隔,路径可以是相对于该JAR包的位置。例如:`Class-Path: lib/dependency1.jar lib/dependency2.jar` 4. 包信息: - Implementation-Title: 实现标题 - Implementation-Version: 实现版本(通常是项目版本) - Implementation-Vendor: 实现的提供者(公司或组织) - Specification-Title: 规范标题 - Specification-Version: 规范版本 - Specification-Vendor: 规范提供者 5. 签名相关(当JAR被签名时会出现): - 会有多个以"Name"开头的节,每个节指定一个文件或一组文件的签名信息,包括摘要算法和签名值。 6. 其他属性: - Sealed: 如果设置为true,则表示这个JAR包是密封的,即不允许其他包在相同的包名下扩展。 注意:MANIFEST.MF文件有严格的格式要求: - 每行最多72个字符,超过则需要换行(以空格开头表示续行)。 - 属性名和值之间用冒号加空格分隔(": ")。 - 每行以回车换行结束(CRLF或LF)。 - 文件最后必须有一个空行。 下面是一个典型的MANIFEST.MF文件示例(参考引用[5]并扩充): ``` Manifest-Version: 1.0 Created-By: Apache Maven 3.8.1 Main-Class: com.example.MainApp Class-Path: lib/gson-2.8.6.jar lib/commons-lang3-3.12.0.jar Implementation-Title: My Application Implementation-Version: 1.0.0 Implementation-Vendor: Example Inc. Specification-Title: My Application Specification Specification-Version: 1.0.0 Specification-Vendor: Example Inc. Sealed: true ``` 解释: - 第一行指定清单文件版本。 - 第二行是创建工具信息。 - 第三行指定主类,这样可以通过`java -jar`命令直接运行。 - 第四行指定类路径,程序运行时会在lib目录下寻找gson和commons-lang3的jar包。 - 接着是包信息,包括实现和规范的标题、版本和供应商。 - 最后一行Sealed设置为true,表示包是密封的。 如果使用Maven打包,可以通过maven-jar-plugin配置MANIFEST.MF(引用[2]和[4])。在Idea中打包时,需要正确指定MANIFEST.MF文件的位置(引用[3])。 相关问题: 1. 如何指定JAR包的主类? 2. 如何在MANIFEST.MF中设置类路径(Class-Path)? 3. 使用Maven打包时如何自定义MANIFEST.MF文件? 4. 如何解决“找不到主清单属性”的错误? 5. 如何查看JAR包中的MANIFEST.MF文件内容? 最后,在回答中注意引用标识,如[^1]。 </think>### JAR包中`MANIFEST.MF`文件内容详解 `MANIFEST.MF`是JAR包的核心配置文件,位于`META-INF/`目录下,采用键值对格式(属性名: 值)。以下是关键属性及其作用: #### 一、基础属性 1. **`Manifest-Version`** 指定清单文件版本号,**必须为首行**: ```manifest Manifest-Version: 1.0 // 固定格式[^1] ``` 2. **`Created-By`** 标识生成JAR包的工具及版本: ```manifest Created-By: Apache Maven 3.8.5 // 如Maven、Gradle等[^2] ``` --- #### 二、核心运行属性 3. **`Main-Class`**(可执行JAR必需) 定义程序入口类(含`main()`方法): ```manifest Main-Class: com.example.MainApp // 全限定类名[^3][^5] ``` - ⚠️ 缺失此属性将导致`java -jar`报错:*"no main manifest attribute"*[^3] 4. **`Class-Path`** 声明依赖库路径(相对JAR包位置): ```manifest Class-Path: lib/gson-2.8.9.jar lib/commons-lang3-3.12.0.jar ``` - 多个路径用**空格分隔**,不支持绝对路径[^5] - 运行时按顺序加载 --- #### 三、包元数据属性 5. **规范信息** ```manifest Specification-Title: My Application API Specification-Version: 2.1 Specification-Vendor: Example Inc. ``` 6. **实现信息** ```manifest Implementation-Title: myapp-core Implementation-Version: 2.1.0-beta Implementation-Vendor: Example Inc. ``` - 用于版本管理及依赖解析[^1][^2] 7. **`Sealed`**(包密封保护) 阻止外部类扩展包内功能: ```manifest Sealed: true // 默认为false[^1] ``` --- #### 四、签名与安全属性 8. **数字签名相关** 当JAR被签名时自动生成: ```manifest Name: com/example/SecureClass.class SHA-256-Digest: base64哈希值 ``` - 用于验证文件完整性 --- ### 文件格式规范 - **语法规则**: - 每行 `属性名: 值`(冒号后必须有空格) - 单行不超过72字符,超长需换行(行首加空格) - 文件末尾需**空行** - **示例完整文件**: ```manifest Manifest-Version: 1.0 Created-By: Apache Maven 3.8.5 Main-Class: com.example.MainApp Class-Path: lib/gson-2.8.9.jar Implementation-Version: 1.0.0 Sealed: true // 此处必须有空行 ``` --- ### 查看方法 ```bash # 解压后直接读取 unzip -p myapp.jar META-INF/MANIFEST.MF # 使用jar命令 jar xf myapp.jar META-INF/MANIFEST.MF && cat META-INF/MANIFEST.MF ``` > ⚠️ 修改警告:手动编辑需严格遵守格式,否则导致JAR失效[^4]。建议通过构建工具(如Maven)自动生成[^2][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值