jar类型文件图标不显示_显示的JAR文件

什么是JAR文件?

JAR文件格式基于流行的ZIP文件格式,并且用于将许多文件聚合为一个文件。 与ZIP文件不同,JAR文件不仅用于归档和分发,还用于库,组件和插件的部署和封装,并且直接由编译器和JVM等工具使用。 JAR中包含的特殊文件(如清单和部署描述符)指导工具如何处理特定的JAR。

可以使用JAR文件:

  • 用于分发和使用类库
  • 作为应用程序和扩展的构建块
  • 作为组件,小程序或插件的部署单元
  • 用于打包与组件关联的辅助资源

JAR文件格式具有许多优点和功能,而传统的存档格式(例如ZIP或TAR)没有提供其中的许多优点和功能。 这些包括:

  • 安全。 您可以对JAR文件的内容进行数字签名。 然后,识别您的签名的工具可以选择授予您的软件安全特权,而该特权本来是不会的,并可以检测代码是否遭到篡改。
  • 减少下载时间。 如果将小程序捆绑在JAR文件中,则浏览器可以在单个HTTP事务中下载小程序的类文件和相关资源,而不必为每个文件打开新的连接。
  • 压缩。 JAR格式允许您压缩文件以进行有效存储。
  • 透明的平台扩展。 Java Extensions Framework提供了一种可以向Java核心平台添加功能的方法,该平台使用JAR文件打包扩展。 (Java 3D和JavaMail是Sun开发的扩展的示例。)
  • 包装密封。 可以选择将JAR文件中存储的软件包密封起来,以增强版本的一致性和安全性。 密封软件包意味着必须在同一JAR文件中找到该软件包中定义的所有类。
  • 软件包版本控制。 JAR文件可以保存有关其包含的文件的数据,例如供应商和版本信息。
  • 可移植性。 处理JAR文件的机制是Java平台核心API的标准部分。

压缩和未压缩的JAR

jar工具(有关详细信息,请参见jar工具 )默认情况下会压缩文件。 通常,未压缩的JAR文件的加载速度比压缩的JAR文件更快,这是因为消除了在加载过程中对文件进行解压缩的需要,但是对于未压缩的文件,通过网络下载的时间可能会更长。

META-INF目录

大多数JAR文件都包含一个META-INF目录,该目录用于存储程序包和扩展配置数据,例如安全性和版本信息。 Java 2平台可以识别和解释META-INF目录中的以下文件或目录,以配置应用程序,扩展和类加载器:

  • 清单文件 清单文件定义了与扩展和软件包有关的数据。
  • INDEX.LIST。 该文件由jar工具的新-i选项生成,并且包含应用程序或扩展中定义的软件包的位置信息。 它是JarIndex实现的一部分,由类加载器用来加速类加载过程。
  • xxx .SF。 这是JAR文件的签名文件。 占位符xxx标识签名者。
  • xxx .DSA。 与签名文件关联的签名块文件存储用于签名JAR文件的公共签名。

jar工具

要使用JAR文件执行基本任务,请使用Java开发工具包中随附的Java存档工具( jar工具)。 您可以使用jar命令调用jar工具。 表1显示了一些常见的应用程序:

表1. jar工具的常用用法

功能 命令
从单个文件创建一个JAR文件 jar cf jar文件输入文件…
从目录创建JAR文件 jar cf jar文件目录名
创建未压缩的JAR文件 jar cf0 jar文件目录名
更新一个JAR文件 jar uf jar文件输入文件…
查看JAR文件的内容 jar tf jar文件
提取JAR文件的内容 jar xf jar文件
从JAR文件中提取特定文件 jar xf jar文件存档文件…
运行打包为可执行JAR文件的应用程序 java -jar app.jar

可执行JAR

可执行jar文件是存储在经过特殊配置的JAR文件中的自包含Java应用程序,可以由JVM直接执行,而无需首先提取文件或设置类路径。 要运行存储在不可执行的JAR中的应用程序,必须将其添加到类路径中,并按名称调用该应用程序的主类。 但是,通过使用可执行的JAR文件,我们可以运行应用程序而无需将其解压缩或知道主入口点。 可执行JAR有助于Java应用程序的轻松分发和执行。

创建可执行的JAR

创建可执行的JAR很容易。 首先将所有应用程序代码放在一个目录中。 假设您应用程序中的主类是com.mycompany.myapp.Sample 。 您想要创建一个包含应用程序代码并标识主类的JAR文件。 为此,请在某处(不在您的应用程序目录中)创建一个名为manifest的文件,并在其中添加以下行:

Main-Class: com.mycompany.myapp.Sample

然后,像这样创建JAR文件:

jar cmf manifest ExecutableJar.jar application-dir

一切就足够了-现在可以使用java -jar执行JAR文件ExecutableJar.jar。

可执行JAR必须通过清单文件的Class-Path标头引用其所需的所有其他依赖JAR。 如果使用-jar选项,则JVM将忽略环境变量CLASSPATH和命令行上指定的任何类路径。

启动可执行JAR

现在,我们已经将应用程序打包到一个名为ExecutableJar.jar的可执行JAR中,我们可以使用以下命令从文件直接启动该应用程序:

java -jar ExecutableJar.jar

包装封口

将程序包密封在JAR文件中意味着必须在同一JAR文件中找到该程序包中定义的所有类。 这允许包作者在打包的类之间强制版本一致性。 密封还提供了一种检测代码篡改的安全措施。

要密封软件包,请为该软件包添加一个Name标头,然后在JAR清单文件中添加一个值为“ true”的Sealed标头。 与可执行JAR一样,可以在创建JAR时通过使用适当的标头元素指定清单文件来密封JAR,如下所示:

Name: com/samplePackage/
Sealed: true

Name标头标识软件包的相对路径名。 它以“ /”结尾,以区别于文件名。 Name标头之后的所有标头(中间无空白行)适用于Name标头中指定的文件或包。 在上面的示例中,由于Sealed标头出现在Name标头之后,中间没有空白行,因此Sealed标头将被解释为仅适用于com/samplePackage包。

如果您尝试从密封包所在的JAR文件之外的其他来源加载密封包中的类,则JVM将抛出SecurityException

扩展包装

扩展将功能添加到Java平台,并且JAR文件格式内置了扩展机制。 扩展机制允许JAR文件通过清单文件中的Class-Path标头指定其他所需的JAR文件。

假设extension1.jar和extension2.jar是同一目录中的两个JAR文件,其中extension1.jar的清单包含以下标头:

Class-Path: extension2.jar

该头文件指示extension2.jar中的类用作扩展类,以用于extension1.jar中的类。 extension1.jar中的类可以调用extension2.jar中的类,而无需extension2.jar成为类路径的一部分。

当加载使用扩展机制的JAR时,JVM会有效地自动将Class-Path头中引用的JAR添加到类路径中。 但是,扩展JAR路径被解释为相对路径,因此通常,扩展JAR必须与引用它的JAR存储在同一目录中。

例如,假设类ExtensionClient ,它引用类ExtensionDemo ,被称为ExtensionClient.jar一个JAR文件中捆绑,并且该类ExtensionDemo在ExtensionDemo.jar捆绑在一起。 为了将ExtensionDemo.jar视为扩展,必须在ExtensionClient.jar清单的Class-Path标头中列出ExtensionDemo.jar,如下所示:

Manifest-Version: 1.0
Class-Path: ExtensionDemo.jar

此清单中的Class-Path标头的值为ExtensionDemo.jar(未指定路径),指示ExtensionDemo.jar与ExtensionClient JAR文件位于同一目录中。

JAR文件中的安全性

可以使用jarsigner工具或直接通过java.security API对JAR文件进行签名。 已签名的JAR文件与原始JAR文件完全相同,除了已更新其清单,并将两个附加文件添加到META-INF目录中,分别是签名文件和签名阻止文件。

使用存储在密钥库数据库中的证书对JAR文件进行签名。 密钥库中存储的证书受密码保护,必须将其提供给jarsigner工具才能对JAR文件进行签名。

图1.密钥库数据库

《jar类型文件图标不显示_显示的JAR文件》

JAR的每个签名者都由签名文件表示,该文件在JAR文件的META-INF目录中具有扩展名.SF。 该文件的格式类似于清单文件-一组RFC-822标头。 如下所示,它由一个主要部分组成,该部分包括签名者提供的但并非特定于任何特定JAR文件条目的信息,其后是清单文件中也必须存在的各个条目的列表。 为了验证来自签名的JAR的文件,将签名文件中的摘要值与针对JAR文件中相应条目计算的摘要进行比较。

清单1.已签名的JAR中的清单文件和签名文件
Contents of signature file META-INF/MANIFEST.MF

Manifest-Version: 1.0
Created-By: 1.3.0 (Sun Microsystems Inc.)

Name: Sample.java
SHA1-Digest: 3+DdYW8INICtyG8ZarHlFxX0W6g=

Name: Sample.class
SHA1-Digest: YJ5yQHBZBJ3SsTNcHJFqUkfWEmI=

Contents of signature file META-INF/JAMES.SF

Signature-Version: 1.0
SHA1-Digest-Manifest: HBstZOJBuuTJ6QMIdB90T8sjaOM=
Created-By: 1.3.0 (Sun Microsystems Inc.)

Name: Sample.java
SHA1-Digest: qipMDrkurQcKwnyIlI3Jtrnia8Q=

Name: Sample.class
SHA1-Digest: pT2DYby8QXPcCzv2NwpLxd8p4G4=

数字签名

数字签名是.SF签名文件的签名版本。 数字签名文件是二进制文件,与.SF文件具有相同的文件名,但具有不同的扩展名。 扩展名取决于数字签名的类型(RSA,DSA或PGP)以及用于签名JAR的证书的类型。

密钥库

要签名JAR文件,首先必须具有一个私钥。 私钥及其关联的公钥证书存储在称为keystores的受密码保护的数据库中。 JDK包含用于创建和修改密钥库的工具。 密钥库中的每个密钥都可以由别名标识,别名通常是拥有密钥的签名者的名字。

使用唯一的别名访问所有密钥库条目(密钥和可信证书条目)。 使用keytool -genkey命令将实体添加到密钥库中以生成密钥对(公钥和私钥)时,将指定别名。 后续的keytool命令必须使用相同的别名来引用实体。

例如,要生成别名为“ james”的新公钥/私钥对并将公钥包装为自签名证书,则可以使用以下命令:

keytool -genkey -alias james -keypass jamespass 
        -validity 80 -keystore jamesKeyStore 
        -storepass jamesKeyStorePass

此命令序列指定后续命令访问密钥库“ jamesKeyStore”中与别名“ james”相关联的私钥所需的初始密码“ jamespass”。 如果密钥库“ jamesKeyStore”不存在, keytool将自动创建它。

jarsigner工具

jarsigner工具使用密钥库来生成或验证JAR文件的数字签名。

假设您已经按照上面的示例创建了密钥库“ jamesKeyStore”,并且其中包含一个别名为“ james”的密钥,则可以使用以下命令对JAR文件进行签名:

jarsigner -keystore jamesKeyStore -storepass jamesKeyStorePass 
          -keypass jamespass -signedjar SSample.jar Sample.jar james

该命令从名为“ jamesKeyStore”的密钥库中使用密码“ jamesKeyStorePass”获取别名为“ james”且密码为“ jamespass”的密钥,并对Sample.jar文件进行签名,从而创建一个签名的JAR SSample.jar。

jarsigner工具还可以验证已签名的JAR文件。 此操作比对JAR文件进行签名要简单得多。 只需执行以下命令:

jarsigner -verify SSample.jar

如果未篡改已签名的JAR文件,则jarsigner工具将告知您JAR已通过验证; 否则,它将抛出SecurityException指示无法验证哪些文件。

还可以使用java.util.jarjava.security API以编程方式对JAR进行签名。 另外,您可以使用诸如Netscape Object Signing Tool之类的工具。

您还可以使用java.util.jarjava.security API以编程方式对JAR进行签名。 (请参阅相关主题的详细信息)。 或者,您可以使用诸如Netscape对象签名工具之类的工具。

JAR索引

如果将应用程序或小程序捆绑到多个JAR文件中,则类加载器将使用简单的线性搜索算法来搜索类路径的每个元素,这可能需要类加载器下载并打开许多JAR文件,直到找到类或资源为止。 如果类加载器尝试查找不存在的资源,则必须下载应用程序或小程序中的所有JAR文件。 对于大型网络应用程序和小程序,这可能会导致启动缓慢,响应缓慢以及网络带宽浪费。

从JDK 1.3开始,JAR文件格式已支持索引,以优化在网络应用程序(尤其是小应用程序)中搜索类的过程。 JarIndex机制收集在applet或应用程序中定义的所有JAR文件的内容,并将该信息存储在第一个JAR文件的索引文件中。 在下载第一个JAR文件之后,小应用程序类加载器将使用收集的内容信息来有效下载JAR文件。 此目录信息存储在根JAR文件的META-INF目录中名为INDEX.LIST的简单文本文件中。

创建一个JarIndex

您可以通过在jar命令中指定-i选项来创建JarIndex。 假设我们有一个目录结构,如下图所示:

图2. JarIndex

《jar类型文件图标不显示_显示的JAR文件》

您将使用以下命令为JarIndex_Main.jar,JarIndex_test.jar和JarIndex_test1.jar创建索引文件:

jar -i JarIndex_Main.jar JarIndex_test.jar SampleDir/JarIndex_test1.jar

INDEX.LIST文件具有简单的格式,其中包含每个索引的JAR文件中包含的包或类的名称,如清单2所示:

清单2. JarIndex INDEX.LIST文件示例
JarIndex-Version: 1.0

JarIndex_Main.jar
sp

JarIndex_test.jar
Sample

SampleDir/JarIndex_test1.jar
org
org/apache
org/apache/xerces
org/apache/xerces/framework
org/apache/xerces/framework/xml4j

摘要

JAR格式不仅仅是存档格式。 它具有许多功能,可以提高Java应用程序的效率,安全性和组织性。 由于这些功能内置于核心平台(包括编译器和类加载器)中,因此开发人员可以利用JAR文件格式的功能来简化和改进其开发和部署过程。

翻译自: https://www.ibm.com/developerworks/java/library/j-jar/index.html

    原文作者:cusi77914
    原文地址: https://blog.csdn.net/cusi77914/article/details/107110979
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞