关于
jar
文件,大家一定都不陌生,平常开发spring boot
打包的时候一般都会打包成单独的 jar 包。大家经常执行 jar 但其实却很少使用 jar 指令,这次就来简单交流下jar
命令的简单使用
jar程序选项
选项 | 说明 |
---|---|
c | 创建一个新的或者空的存档文件并加入文件。如果指定的文件名是目录,jar 程序将会对他们进行递归处理 |
C | 临时改变目录,例如:jar cvf jarFileName.jar -C classes *.class 切换到 classes 子目录以便增加类文件 |
e | 在清单文件中创建一个入口点 |
f | 指定 JAR 文件名作为第二个命令行参数。如果没有这个参数,jar 命令会将结果写至标准输出(在创建JAR文件时)或者从标准输入读取(在解压或者列出JAR文件内容时) |
i | 建立索引文件(建立索引文件(用于加快大型归档中的查找)) |
m | 将一个清单文件添加到 JAR 文件中。清单是对归档内容和来源的一个说明。每个归档有一个默认的清单文件。但是,如果想验证归档文件的内容,可以提供自己的清单文件 |
M | 不为条目创建清单文件 |
t | 显示内容表 |
u | 更新一个已有的 JAR 文件 |
v | 生成详细的输出结果 |
x | 解压文件。如果提供一个或多个文件名,只解压这些文件;否则,解压所有文件 |
0 | 存储,但不进行 ZIP 压缩 |
上面列出了 jar 指令会用到的参数选项,这里我将简单通过几个选项来执行几个操作
创建 JAR 文件
jar cvf [JAR 文件名] [文件1] [文件2] ...
示例:
我们可以先准备一个用来测试的文件夹,并创建一个需要被 jar 打包的文件
mkdir HelloWorld
cd HelloWorld
# 可以编写一个简单的java程序
vim HelloWorld.java
# 编译java程序
javac HelloWorld.java
# 执行打包指令
jar cvf hello-world.jar HelloWorld.class
# 查看JAR包中的文件
jar tf hello-world.jar
# 执行 JAR 文件 (注:这里会失败,因为我们并没有配置这个JAR包的执行入口)
java -jar hello-world.jar
HelloWorld.java
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
设置 JAR 文件执行入口
在上述的创建过程最后,我们尝试执行了我们创建的 JAR 文件,却并没有得到想要的结果,而是输出了:
no main manifest attribute, in hello-world.jar
前两个单词就非常明显的告诉了我们 no main,也就是没有入口。下面我会简单介绍两个方式去添加入口
e 指令参数
在上面的表单中有提到,其作用就是创建一个入口
# 因为我们已经有了一个jar包,这里我没有选择重新打包,而是已更新的形式,也就是 u 参数配合 e 告诉 jar包 main 在 HelloWorld 这个类中
jar ufe hello-world.jar HelloWorld
# 这样我们就可以执行了
java -jar hello-world.jar
manifest
还有一个方法就是直接配置修改 manifest 文件,在上述 e参数描述中,完整的说法是在清单文件中创建一个入口点,而这个清单文件指的就是 manifest 文件,默认在创建 JAR 包时都会被创建出来,我们在创建查看 JAR 包中的文件里就能看到这个文件,而这个文件同样可以让我们直接自定义
# 因为原先的文件已存在一个 manifest 文件,我们这里进行重新打包,
# 当然也可以通过 ufm 进行新增 manifest 文件,但因为上面我们已经添加了 main class,
# 所以这里我重新进行打包操作
rm hello-world.jar
# 创建一个自定义的manifest-custom.mf文件
vim manifest-custom.mf
# 打包 这里要注意如果使用时 cvmf 需要替换 mf 与 jar 文件名的指令位置
jar cvfm hello-world.jar manifest-custom.mf *.class
# 执行
java -jar hello-world.jar
manifest-custom.mf
Manifest-Version: 1.0
Build-By: baeldung
Create-By: 17.0.2 (OracleJDK)
Main-Class: HelloWorld
上面的配置分别代表
- manifest 版本
- 构建人
- 创建的JDK版本
- main 类入口
manifest 的配置还有很多,不只这些,并且支持多文件,有兴趣的伙伴可以研究下,配合 jar指令的学习逐渐深入
相关阅读
[1]: Understanding the JAR Manifest
[2]: Using JAR Files: The Basics
[3]: IOException: 'Invalid header field; when creating .jar file with manifest