⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jar 文件揭密.htm

📁 详细介绍了jar 文件如何打包
💻 HTM
📖 第 1 页 / 共 4 页
字号:
      <TABLE cellSpacing=0 cellPadding=3 width="100%" border=1>
        <TBODY>
        <TR>
          <TD><B>功能</B></TD>
          <TD><B>命令</B></TD></TR>
        <TR>
          <TD>用一个单独的文件创建一个 JAR 文件</TD>
          <TD>jar cf jar-file input-file...</TD></TR>
        <TR>
          <TD>用一个目录创建一个 JAR 文件</TD>
          <TD>jar cf jar-file dir-name</TD></TR>
        <TR>
          <TD>创建一个未压缩的 JAR 文件</TD>
          <TD>jar cf0 jar-file dir-name</TD></TR>
        <TR>
          <TD>更新一个 JAR 文件</TD>
          <TD>jar uf jar-file input-file...</TD></TR>
        <TR>
          <TD>查看一个 JAR 文件的内容</TD>
          <TD>jar tf jar-file</TD></TR>
        <TR>
          <TD>提取一个 JAR 文件的内容</TD>
          <TD>jar xf jar-file</TD></TR>
        <TR>
          <TD>从一个 JAR 文件中提取特定的文件</TD>
          <TD>jar xf jar-file archived-file...</TD></TR>
        <TR>
          <TD>运行一个打包为可执行 JAR 文件的应用程序</TD>
          <TD>java -jar app.jar</TD></TR></TBODY></TABLE></P>
      <P><A name=IDAZHWVB><SPAN class=atitle2>可执行的 JAR</SPAN></A><BR>一个<I>可执行的 
      jar</I> 文件是一个自包含的 Java 应用程序,它存储在特别配置的JAR 文件中,可以由 JVM 
      直接执行它而无需事先提取文件或者设置类路径。要运行存储在非可执行的 JAR 
      中的应用程序,必须将它加入到您的类路径中,并用名字调用应用程序的主类。但是使用可执行的 JAR 
      文件,我们可以不用提取它或者知道主要入口点就可以运行一个应用程序。可执行 JAR 有助于方便发布和执行 Java 应用程序。</P>
      <P><A name=IDAGYWVB><SPAN class=atitle3>创建可执行 JAR</SPAN></A><BR>创建一个可执行 
      JAR 很容易。首先将所有应用程序代码放到一个目录中。假设应用程序中的主类是 
      <CODE>com.mycompany.myapp.Sample</CODE>。您要创建一个包含应用程序代码的 JAR 
      文件并标识出主类。为此,在某个位置(不是在应用程序目录中)创建一个名为<CODE> manifest</CODE> 
      的文件,并在其中加入以下一行:</P>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
Main-Class: com.mycompany.myapp.Sample
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>然后,像这样创建 JAR 文件:</P>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
jar cmf manifest ExecutableJar.jar application-dir
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>所要做的就是这些了 -- 现在可以用<CODE> java -jar</CODE> 执行这个 JAR 文件 
      ExecutableJar.jar。</P>
      <P>一个可执行的 JAR 必须通过 menifest 文件的头引用它所需要的所有其他从属 JAR。如果使用了 <CODE>-jar</CODE> 
      选项,那么环境变量 CLASSPATH 和在命令行中指定的所有类路径都被 JVM 所忽略。</P>
      <P><A name=IDALZWVB><SPAN class=atitle3>启动可执行 
      JAR</SPAN></A><BR>既然我们已经将自己的应用程序打包到了一个名为 ExecutableJar.jar 的可执行 JAR 
      中了,那么我们就可以用下面的命令直接从文件启动这个应用程序:</P>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
java -jar ExecutableJar.jar
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P><A name=IDAWZWVB><SPAN class=atitle2>包密封</SPAN></A><BR>密封 JAR 
      文件中的一个包意味着在这个包中定义的所有类都必须在同一个 JAR 
      文件中找到。这使包的作者可以增强打包类之间的版本一致性。密封还提供了防止代码篡改的手段。</P>
      <P>要密封包,需要在 JAR 的 manifest 文件中为包添加一个<CODE> Name</CODE> 
      头,然后加上值为“true”的<CODE> Sealed</CODE> 头。与可执行的 JAR 一样,可以在创建 JAR 
      时,通过指定一个具有适当头元素的 manifest 文件密封一个 JAR,如下所示:</P>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
Name: com/samplePackage/
Sealed: true
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P><CODE>Name</CODE> 头标识出包的相对路径名。它以一个“/”结束以与文件名区别。在 <CODE>Name</CODE> 
      头后面第一个空行之前的所有头都作用于在 <CODE>Name</CODE> 头中指定的文件或者包。在上述例子中,因为<CODE> 
      Sealed</CODE> 头出现在 <CODE>Name</CODE> 头后并且中间没有空行,所以 <CODE>Sealed</CODE> 
      头将被解释为只应用到包<CODE> com/samplePackage</CODE> 上。</P>
      <P>如果试图从密封包所在的 JAR 文件以外的其他地方装载密封包中的一个类,那么 JVM 将抛出一个 
      <CODE>SecurityException</CODE>。</P>
      <P><A name=IDAM1WVB></A>扩展打包<BR>扩展为 Java 平台增加了功能,在 JAR 
      文件格式中已经加入了扩展机制。扩展机制使得 JAR 文件可以通过 manifest 文件中的 <CODE>Class-Path</CODE> 
      头指定所需要的其他 JAR 文件。</P>
      <P>假设 extension1.jar 和 extension2.jar 是同一个目录中的两个 JAR 文件,extension1.jar 的 
      manifest 文件包含以下头:</P>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
Class-Path: extension2.jar
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>这个头表明 extension2.jar 中的类是 extension1.jar 中的类的<I>扩展类</I>。extension1.jar 
      中的类可以调用 extension2.jar 中的类,并且不要求 extension2.jar 处在类路径中。</P>
      <P>在装载使用扩展机制的 JAR 时,JVM 会高效而自动地将在<CODE>Class-Path</CODE> 头中引用的 JAR 
      添加到类路径中。不过,扩展 JAR 路径被解释为相对路径,所以一般来说,扩展 JAR 必须存储在引用它的 JAR 所在的同一目录中。</P>
      <P>例如,假设类<CODE> ExtensionClient</CODE> 引用了类<CODE> 
      ExtensionDemo</CODE>,它捆绑在一个名为 ExtensionClient.jar 的 JAR 文件中,而类<CODE> 
      ExtensionDemo</CODE> 则捆绑在 ExtensionDemo.jar 中。为了使 ExtensionDemo.jar 
      可以成为扩展,必须将 ExtensionDemo.jar 列在 ExtensionClient.jar 的 manifest 的<CODE> 
      Class-Path</CODE> 头中,如下所示:</P>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
Manifest-Version: 1.0
Class-Path: ExtensionDemo.jar
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>在这个 manifest 中 <CODE>Class-Path</CODE> 头的值是没有指定路径的 ExtensionDemo.jar,表明 
      ExtensionDemo.jar 与 ExtensionClient JAR 文件处在同一目录中。</P>
      <P><A name=IDA32WVB><SPAN class=atitle2>JAR 文件中的安全性</SPAN></A><BR>JAR 
      文件可以用 <CODE>jarsigner</CODE> 工具或者直接通过<CODE> java.security</CODE> API 
      签名。一个签名的 JAR 文件与原来的 JAR 文件完全相同,只是更新了它的 manifest,并在 META-INF 
      目录中增加了两个文件,一个签名文件和一个签名块文件。</P>
      <P>JAR 文件是用一个存储在 <I>Keystore</I> 数据库中的证书签名的。存储在 keystore 中的证书有密码保护,必须向 
      <CODE>jarsigner</CODE> 工具提供这个密码才能对 JAR 文件签名。</P>
      <P><A name=IDAV3WVB><B>图 1. Keystore 数据库</B></A><BR><IMG height=117 
      alt="Keystore 数据库" src="JAR 文件揭密_files/keystoredatabase.gif" 
width=324></P>
      <P>JAR 的每一位签名者都由在 JAR 文件的 META-INF 目录中的一个具有 .SF 扩展名的签名文件表示。这个文件的格式类似于 
      manifest 文件 -- 一组 RFC-822 头。如下所示,它的组成包括一个主要部分,它包括了由签名者提供的信息、但是不特别针对任何特定的 
      JAR 文件项,还有一系列的单独的项,这些项也必须包含在 menifest 文件中。在验证一个签名的 JAR 时,将签名文件的摘要值与对 JAR 
      文件中的相应项计算的摘要值进行比较。</P><A name=IDAA4WVB><B>清单 1. 签名 JAR 中的 Manifest 和 
      signature 文件</B></A><BR>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE><SPAN class=boldcode>Contents of signature file META-INF/MANIFEST.MF</SPAN>

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=

<SPAN class=boldcode>Contents of signature file META-INF/JAMES.SF</SPAN>

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=
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P><A name=IDAL4WVB><SPAN class=atitle3>数字签名</SPAN></A><BR>一个数字签名是.SF 
      签名文件的已签名版本。数字签名文件是二进制文件,并且与 .SF 文件有相同的文件名,但是扩展名不同。根据数字签名的类型 -- RSA、DSA 或者 
      PGP -- 以及用于签名 JAR 的证书类型而有不同的扩展名。</P>
      <P><A name=IDA14WVB><SPAN class=atitle3>Keystore</SPAN></A><BR>要签名一个 JAR 
      文件,必须首先有一个私钥。私钥及其相关的公钥证书存储在名为 <CODE>keystores</CODE> 的、有密码保护的数据库中。JDK 
      包含创建和修改 keystores 的工具。keystore 中的每一个密钥都可以用一个别名标识,它通常是拥有这个密钥的签名者的名字。</P>
      <P>所有 keystore 项(密钥和信任的证书项)都是用唯一别名访问的。别名是在用 <CODE>keytool -genkey</CODE> 
      命令生成密钥对(公钥和私钥)并在 keystore 中添加项时指定的。之后的<CODE> keytool</CODE> 
      命令必须使用同样的别名引用这一项。</P>
      <P>例如,要用别名“james”生成一个新的公钥/私钥对并将公钥包装到自签名的证书中,要使用下述命令:</P>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
keytool -genkey -alias james -keypass jamespass 
        -validity 80 -keystore jamesKeyStore 
        -storepass jamesKeyStorePass
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>这个命令序列指定了一个初始密码“jamespass”,后续的命令在访问 keystore 
      “jamesKeyStore”中与别名“james”相关联的私钥时,就需要这个密码。如果 
      keystore“jamesKeyStore”不存在,则<CODE> keytool</CODE> 会自动创建它。</P>
      <P><A name=IDAZ5WVB><SPAN class=atitle3>jarsigner 
      工具</SPAN></A><BR><CODE>jarsigner</CODE> 工具使用 keystore 生成或者验证 JAR 
      文件的数字签名。</P>
      <P>假设像上述例子那样创建了 keystore “jamesKeyStore”,并且它包含一个别名为“james”的密钥,可以用下面的命令签名一个 
      JAR 文件:</P>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
jarsigner -keystore jamesKeyStore -storepass jamesKeyStorePass 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -