JAR 是一种用于将多个文件打包成一个单独文件的工具,它在 Java 开发中非常重要,用于打包、分发和部署 Java 应用程序。以下是关于 JAR 的详细介绍,包括其概念、工具以及相关的命令和函数。
1. JAR 的概念
1.1 定义
JAR(Java Archive)是 Java 的归档文件格式,它将多个文件(如 Java 类文件、资源文件、配置文件等)打包到一个单独的文件中。JAR 文件本质上是一个压缩文件,类似于 ZIP 文件,但它还包含了一些特殊的元数据,例如 MANIFEST.MF
文件,用于描述 JAR 文件的内容和属性。
1.2 作用
- 打包资源:将 Java 应用程序的所有类文件、资源文件(如图片、配置文件等)打包到一个文件中,方便管理和分发。
- 模块化:通过 JAR 文件可以将相关的类和资源组织在一起,形成一个模块化的单元。
- 版本管理:可以对 JAR 文件进行版本控制,方便更新和维护。
- 可执行性:如果 JAR 文件包含
MANIFEST.MF
文件,并且指定了主类,那么可以直接运行 JAR 文件,就像运行一个可执行文件一样。
2. JAR 工具
JAR 工具是 JDK 自带的一个命令行工具,用于创建、更新、查看和提取 JAR 文件。它位于 JDK 的 bin
目录下,通常可以通过命令行直接调用。
2.1 常用命令
2.1.1 创建 JAR 文件
命令格式:
jar cvf jar-file input-file(s)
c
:表示创建新的 JAR 文件。v
:表示在创建过程中显示详细信息。f
:表示指定 JAR 文件的名称。jar-file
:指定生成的 JAR 文件的名称。input-file(s)
:指定要打包的文件或目录。
示例:
假设有一个目录 myapp
,其中包含以下文件结构:
myapp/
├── Main.class
├── Helper.class
└── config.properties
可以通过以下命令将这些文件打包成一个 JAR 文件:
jar cvf myapp.jar myapp/
执行后,会在当前目录下生成一个名为 myapp.jar
的文件,并且会显示打包过程中的详细信息,例如:
added manifest
adding: myapp/Main.class(in = 234) (out= 156)(deflated 33%)
adding: myapp/Helper.class(in = 123) (out= 89)(deflated 27%)
adding: myapp/config.properties(in = 56) (out= 45)(deflated 19%)
2.1.2 查看 JAR 文件内容
命令格式:
jar tf jar-file
t
:表示列出 JAR 文件中的内容。f
:指定要查看的 JAR 文件。
示例:
查看刚才创建的 myapp.jar
文件的内容:
jar tf myapp.jar
输出结果可能如下:
META-INF/
META-INF/MANIFEST.MF
myapp/
myapp/Main.class
myapp/Helper.class
myapp/config.properties
2.1.3 提取 JAR 文件内容
命令格式:
jar xf jar-file
x
:表示提取 JAR 文件中的内容。f
:指定要提取的 JAR 文件。
示例:
提取 myapp.jar
文件中的所有内容到当前目录:
jar xf myapp.jar
执行后,当前目录下会重新生成 myapp
文件夹及其内容。
2.1.4 更新 JAR 文件
命令格式:
jar uf jar-file input-file(s)
u
:表示更新 JAR 文件。f
:指定要更新的 JAR 文件。input-file(s)
:指定要添加或更新的文件。
示例:
假设需要将一个新文件 newfile.txt
添加到 myapp.jar
中:
jar uf myapp.jar newfile.txt
执行后,myapp.jar
文件会被更新,包含新的文件 newfile.txt
。
2.1.5 创建可执行 JAR 文件
要创建一个可执行的 JAR 文件,需要在 MANIFEST.MF
文件中指定主类(即包含 main
方法的类)。
步骤:
-
创建一个
MANIFEST.MF
文件,内容如下:Main-Class: myapp.Main
其中
myapp.Main
是包含main
方法的类的全限定名。 -
使用以下命令创建可执行 JAR 文件:
jar cvfm myapp.jar MANIFEST.MF myapp/
m
:表示指定自定义的MANIFEST.MF
文件。
示例:
假设 myapp/Main.class
是主类,创建一个可执行的 JAR 文件:
-
创建
MANIFEST.MF
文件,内容为:Main-Class: myapp.Main
-
执行命令:
jar cvfm myapp.jar MANIFEST.MF myapp/
-
运行可执行 JAR 文件:
java -jar myapp.jar
3. JAR 文件中的 MANIFEST.MF 文件
MANIFEST.MF
是 JAR 文件中的一个特殊文件,位于 META-INF
目录下。它包含了一些元数据,用于描述 JAR 文件的属性和配置。
3.1 主要属性
- Main-Class:指定 JAR 文件的主类,用于创建可执行 JAR 文件。
- Class-Path:指定 JAR 文件运行时需要的其他依赖 JAR 文件或目录。
- Extension-List:指定扩展模块列表。
- Name:指定条目名称,用于指定特定文件或目录的属性。
3.2 示例
假设有一个 JAR 文件,其 MANIFEST.MF
文件内容如下:
Manifest-Version: 1.0
Created-By: 1.8.0_231 (Oracle Corporation)
Main-Class: myapp.Main
Class-Path: lib/dependency1.jar lib/dependency2.jar
Main-Class
指定了主类为myapp.Main
。Class-Path
指定了运行时需要的依赖 JAR 文件路径。
4. JAR 文件的依赖管理
在实际开发中,JAR 文件往往需要依赖其他 JAR 文件。可以通过以下几种方式管理依赖:
- 将依赖 JAR 文件打包到同一个 JAR 文件中:这种方式会导致 JAR 文件体积增大,但运行时不需要额外的依赖。
- 指定依赖 JAR 文件的路径:通过
MANIFEST.MF
文件中的Class-Path
属性指定依赖 JAR 文件的路径。 - 使用工具管理依赖:例如 Maven 或 Gradle,这些工具可以自动管理依赖关系,生成包含依赖的 JAR 文件。
5. JAR 文件的签名
为了保证 JAR 文件的安全性和完整性,可以对 JAR 文件进行签名。签名后的 JAR 文件可以验证其来源和完整性。
5.1 签名步骤
-
生成密钥库:使用
keytool
工具生成密钥库。keytool -genkey -keystore mykeystore -alias myalias
-
签名 JAR 文件:使用
jarsigner
工具对 JAR 文件进行签名。jarsigner -keystore mykeystore myapp.jar myalias
-
验证签名:使用以下命令验证 JAR 文件的签名。
jarsigner -verify myapp.jar
6. JAR 文件的高级用法
6.1 嵌套 JAR 文件
可以在一个 JAR 文件中嵌套另一个 JAR 文件。这种方式可以用于模块化开发,将不同的功能模块打包到不同的 JAR 文件中,然后在一个主 JAR 文件中引用它们。
示例:
假设有一个主 JAR 文件 mainapp.jar
和一个依赖的 JAR 文件 dependency.jar
,可以在 mainapp.jar
的 MANIFEST.MF
文件中指定依赖路径:
Class-Path: dependency.jar
然后将 dependency.jar
放在与 mainapp.jar
同一目录下,运行时 JVM 会自动加载依赖的 JAR 文件。
6.2 使用 JAR 文件作为资源
在 Java 程序中,可以通过 ClassLoader
加载 JAR 文件中的资源文件。例如,可以通过以下代码加载 JAR 文件中的 config.properties
文件:
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("myapp/config.properties");
Properties properties = new Properties();
properties.load(inputStream);
这种方式可以方便地访问 JAR 文件中的资源文件,而不需要解压 JAR 文件。
7. JDK 中与 JAR 相关的其他工具
7.1 jdeps
工具
jdeps
是 JDK 自带的一个工具,用于分析 Java 应用程序的依赖关系。它可以显示类文件或 JAR 文件之间的依赖关系。
示例:
分析 myapp.jar
文件的依赖关系:
jdeps myapp.jar
输出结果可能如下:
myapp.jar -> /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar
myapp.Main -> java.lang.Object
myapp.Main -> java.lang.System
myapp.Main -> myapp.Helper
7.2 jmod
工具
jmod
是 JDK 9 引入的一个工具,用于创建和操作 Java 模块文件(.jmod
文件)。虽然它与 JAR 文件不完全相同,但在模块化开发中,它与 JAR 文件密切相关。
示例:
创建一个模块文件:
jmod create mymodule.jmod mymodule/
然后可以将模块文件打包到 JAR 文件中,或者直接使用模块文件进行模块化开发。
总结
JAR 是 Java 开发中非常重要的工具,它不仅可以用于打包和分发 Java 应用程序,还可以通过 MANIFEST.MF
文件实现可执行性、依赖管理和模块化等功能。通过 JDK 自带的 jar
工具,可以方便地创建、更新、查看和提取 JAR 文件。此外,jdeps
和 jmod
等工具也为 JAR 文件的使用提供了更多的支持。