0%

java打包

Java 打包详解:使用 jar 命令创建与管理 JAR 文件

JAR(Java Archive)文件是 Java 平台中用于打包类、资源和元数据的归档格式,可用于分发库、应用程序或组件。jar 命令是 JDK 自带的打包工具,支持创建、查看、更新和提取 JAR 文件。本文将详细讲解 jar 命令的用法、参数含义及实战示例,帮助你熟练掌握 Java 打包技巧。

jar 命令基本语法

jar 命令的通用格式如下:

1
jar {操作选项}[参数] [JAR文件名] [清单文件] [入口类] [-C 目录] 文件...

核心操作选项(必选其一)

选项 功能描述
-c 创建新的 JAR 文件(若文件已存在,会覆盖)。
-t 列出 JAR 文件中的内容(目录和文件列表)。
-x 从 JAR 文件中提取指定文件(不指定则提取所有文件)。
-u 更新现有 JAR 文件(添加新文件或替换已有文件)。
-i 为 JAR 文件生成索引信息(加速类加载)。

辅助参数(可选)

选项 功能描述
-v 生成详细输出(显示打包 / 提取的文件列表及进度)。
-f 指定 JAR 文件名(必须紧跟文件名,如 -f app.jar)。
-m 合并指定的清单文件(MANIFEST.MF)到 JAR 中(需指定清单文件路径)。
-e 指定可执行 JAR 的入口类(主类,包含 main 方法)。
-0 仅存储文件,不压缩(适合已压缩的资源,如图片、ZIP)。
-M 不自动生成清单文件(默认会生成基础清单)。
-C 切换到指定目录,再包含后续文件(用于打包其他目录的文件,保持目录结构)。
-P 保留文件的绝对路径或父目录信息(不推荐,可能导致路径混乱)。

jar 命令实战示例

创建 JAR 文件

(1)基本打包(含类文件)

将当前目录下的 Foo.classBar.class 打包为 classes.jar

1
jar cvf classes.jar Foo.class Bar.class
  • c:创建新 JAR;v:显示详细信息;f:指定文件名 classes.jar

  • 输出示例:

    1
    2
    3
    已添加清单
    正在添加: Foo.class(输入 = 890) (输出 = 543)(压缩了 38%)
    正在添加: Bar.class(输入 = 1024) (输出 = 621)(压缩了 39%)
(2)打包目录(含子目录)

src 目录下的所有文件(含子目录)打包为 app.jar

1
jar cvf app.jar src/
  • 注意:目录会被递归处理,保留原目录结构(如 src/com/xxx/Class.class)。
(3)指定清单文件

使用自定义清单文件 mymanifest.mf 打包(覆盖默认清单):

1
jar cvfm app.jar mymanifest.mf -C bin/ .
  • -m:指定清单文件 mymanifest.mf
  • -C bin/ .:切换到 bin 目录,打包所有文件(. 表示当前目录,即 bin 下的内容)。
(4)创建可执行 JAR(带主类)

打包并指定入口类 com.example.Main(含 main 方法),可直接通过 java -jar 运行:

1
jar cvfe app.jar com.example.Main -C target/classes/ .
  • -e com.example.Main:指定主类;
  • 运行方式:java -jar app.jar

查看 JAR 文件内容

列出 app.jar 中的所有文件和目录:

1
2
3
jar tf app.jar  # 简洁输出
# 或带详细信息(大小、修改时间)
jar tvf app.jar
  • 输出示例(简洁版):

    1
    2
    3
    4
    5
    META-INF/
    META-INF/MANIFEST.MF
    com/
    com/example/
    com/example/Main.class

提取 JAR 文件内容

(1)提取所有文件

app.jar 中的所有内容提取到当前目录:

1
jar xf app.jar
  • 提取后会还原 JAR 中的目录结构(如 META-INF/com/ 等)。
(2)提取指定文件

仅提取 app.jar 中的 com/example/Main.class

1
jar xf app.jar com/example/Main.class

更新 JAR 文件

向现有 app.jar 中添加新文件 config.properties

1
jar uf app.jar config.properties
  • 若文件已存在,会覆盖旧版本;
  • -v 可查看详细更新信息:jar uvf app.jar config.properties

生成索引文件

为大型 JAR 生成索引(加速类加载,多 JAR 依赖时有用):

1
jar i app.jar
  • 生成 META-INF/INDEX.LIST,记录 JAR 中的类信息。

清单文件(MANIFEST.MF)详解

清单文件是 JAR 中的元数据文件,位于 META-INF/MANIFEST.MF,用于描述 JAR 的属性(如主类、版本、依赖等)。

默认清单内容

创建 JAR 时,若不指定 -m,会自动生成基础清单:

1
2
Manifest-Version: 1.0
Created-By: 1.8.0_381 (Oracle Corporation)

关键属性(自定义清单)

属性 作用描述
Main-Class 可执行 JAR 的入口类(如 com.example.Main),配合 java -jar 运行。
Class-Path 指定 JAR 依赖的其他 JAR 路径(空格分隔,相对路径)。
Implementation-Title 应用名称。
Implementation-Version 应用版本。
示例:可执行 JAR 的清单
1
2
3
4
5
Manifest-Version: 1.0
Created-By: 1.8.0_381
Main-Class: com.example.Main
Class-Path: lib/utils.jar lib/log4j.jar
Implementation-Version: 1.0.0
  • 打包时通过 -m 引入该清单:jar cvfm app.jar manifest.mf -C classes/ .

清单文件格式注意事项

  • 每行格式:属性名: 值(冒号后必须有空格)。
  • 换行规则:长行需在第二行开头加空格(续行)。
  • 编码:默认 UTF-8,不可包含非 ASCII 字符(除非编码正确)。

可执行 JAR 的运行与原理

运行可执行 JAR

1
java -jar app.jar
  • 要求清单文件中指定Main-Class,否则需手动指定主类:

    1
    java -cp app.jar com.example.Main  # -cp 指定类路径

原理

  • 可执行 JAR 本质是包含 Main-Class 属性的普通 JAR。
  • java -jar 会优先读取清单中的 Main-Class,并调用其 main 方法。

常见问题与解决方案

1. “没有主清单属性” 错误

  • 原因:JAR 未指定 Main-Class,或清单格式错误。
  • 解决:重新打包并通过 -e 指定主类,或在清单中添加 Main-Class: 全类名

2. 依赖 JAR 无法找到

  • 原因:依赖的 JAR 不在 Class-Path 指定的路径下。
  • 解决:
    • 在清单中通过 Class-Path 正确配置依赖路径(相对或绝对路径)。
    • 或使用工具(如 Maven/Gradle)将依赖打包到 JAR 中(-fat jar)。

3. 中文文件名乱码

  • 原因:jar 命令依赖系统默认编码,非 UTF-8 环境可能乱码。

  • 解决:指定编码(仅部分 JDK 版本支持):

    1
    jar cvf app.jar -Dfile.encoding=UTF-8 文件名

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10