在Java中使用 JAR 和 Manifest 文件
先决条件 - JAR 文件格式
每当开发人员想要分发他的软件的一个版本时,他想要的只是分发一个文件,而不是一个充满类文件的目录结构。 JAR 文件就是为此目的而设计的。 JAR 文件可以包含类文件和其他文件类型,例如项目中可能包含的声音和图像文件。 JAR 文件中的所有文件都使用类似于 zip 的格式进行压缩。
创建 JAR 文件 - 更多选项
jar 文件是使用 jar 工具创建的。一般命令看起来有点像这样:
jar options jar-file [manifest-file] file1 file2 file3 ...
- jar – 文件:要在其上使用 jar 工具的 jar 文件的名称。
- file1, file2, file3 :要添加到 jar 文件中的文件。 manifest-file 是包含该 jar 文件清单的文件的名称,将 manifest-file 作为参数是完全可选的。
- c :创建一个新的或空的存档并向其中添加文件。如果任何指定的文件名是目录,则 jar 程序会递归地处理它们。
- C : 临时更改目录。
- e :在清单中创建一个入口点。
- f :将 JAR 文件名指定为第二个命令行参数。如果缺少此参数,jar 会将结果写入标准输出(创建 JAR 文件时)或从标准输入读取结果(提取或制表 JAR 文件时)。
- i :创建一个索引文件。
- m :将清单文件添加到 JAR 文件中。清单是对存档内容和来源的描述。每个档案都有一个默认清单,但如果您想验证档案的内容,您可以提供自己的清单。
- M :不为条目创建清单文件。
- t :显示目录。
- u :更新现有的 JAR 文件。
- v :生成详细输出。
- x :提取文件。如果您提供一个或多个文件名,则仅提取那些文件,否则提取所有文件。
- 0 :存储没有 zip 压缩。
jar 命令的选项与 UNIX tar 命令的选项几乎相似。在 Windows 中,您还可以通过在 cmd 中键入 jar 然后按回车来获得有关 jar 命令的各种选项的帮助,输出将类似于以下内容:
例子 :
要创建一个包含两个类 server.class 和 client.class 以及一个 Jpeg 图像 logo.jpeg 的 JAR 文件,需要编写以下命令:
jar cvf chat.jar server.class client.class logo.jpeg
上述命令的输出会有点像这样:
最好将-v选项与 jar 命令一起使用,因为您将了解事情的进展情况。
清单文件
每个 JAR 文件都包含一个清单文件,用于描述存档的功能。默认情况下,每个 JAR 文件都有一个清单文件。默认清单文件被命名为 MANIFEST.MF 并且存在于存档的 META-INF 子目录中。虽然默认清单文件只包含两个条目,但复杂的清单文件可以有更多。这是默认清单文件的样子 -
清单文件的条目被分组为多个部分。每个部分有两个条目部分名称及其值。稍后我们将看到这些部分如何真正帮助我们控制存档的属性。清单文件也可以使用 jar 命令的m选项进行更新。但是在更新清单文件时需要牢记某些事情,否则您可能会收到以下令人毛骨悚然的消息。
java.io.IOException: invalid manifest format
处理 Manifest 文件时要记住的事项:
- 您应该在清单文件中任何部分的名称和值之间留有空格,例如 Version:1.1 在有效部分中,而不是写 Version: 1.1 冒号和 1.1 之间的空格真的很重要。
- 在指定主类时,您不应在类名末尾添加 .class 扩展名。只需键入以下内容即可指定主类:
Main-Class: Classname
(我将很快介绍 Main-Class 部分)。
- 您必须在文件末尾添加换行符。您无需编写 \n 来指定换行符,只需将清单文件的最后一行留空即可。
- 清单的文本文件必须使用 UTF-8 编码,否则您可能会遇到一些麻烦。
例子:
现在让我们回来更新 chat.jar 档案的内容。要更新清单文件,我们只需要编写以下命令:
jar uvfm chat.jar manifest.txt
这里 manifest.txt 是新的 manifest 文件,内容如下:
上述命令的输出会有点像这样:
在这里,我们收到两个警告,因为我们正试图覆盖以前存在的条目。
可执行 Jar 文件
您可以使用 jar 命令的e选项来指定程序的入口点,即。启动Java应用程序时通常要调用的类。
例子:
要创建以客户端类作为主类的 chat.jar 文件,您需要编写以下命令 -
jar cvfe chat.jar client client.class server.class logo.jpeg
上述命令的输出会有点像这样:
切记不要在要设置主类的类名称后添加 .class 扩展名。
或者,您可以在清单文件中添加一个 Main-Class 条目,然后对其进行更新。对于上面的示例,您只需要添加以下条目:
Main-Class: client
设置主类后,只需编写以下命令即可运行 jar 程序 -
java -jar chat.jar
根据操作系统配置,用户甚至可以通过双击 JAR 文件图标来启动应用程序。
包装密封
最后,我们将讨论Java中的包密封。我们可以在Java中密封一个包,以确保没有其他类可以将自己添加到其中。如果您在代码中使用包可见类、方法和字段,则可能需要密封包。如果没有包密封,其他类可以将自己添加到同一个包中,从而可以访问包的可见特性。
- 要实现包密封,只需将该包的所有类放入一个 JAR 文件中。
- 默认情况下,jar 文件中的包不是密封的,但可以通过在清单文件中添加几行来更改全局默认值。
- 让我们再次考虑一下我们的 chat.jar 存档的情况,现在类 client.class 和 server.class 的包是应用程序,我们想要密封这个包,我们需要做的就是在清单文件中添加以下行并更新它.
Name: application Sealed: true