# 下载扩展程序

> 原文： [https://docs.oracle.com/javase/tutorial/ext/basics/download.html](https://docs.oracle.com/javase/tutorial/ext/basics/download.html)

下载扩展是 JAR 文件中的类（和相关资源）的集合。 JAR 文件的清单可以包含引用一个或多个下载扩展的标头。可以通过以下两种方式之一引用扩展：

*   通过 `Class-Path` 标头
*   通过 `Extension-List` 标题

请注意，清单中最多允许使用其中一个。由 `Class-Path` 标头指示的下载扩展名仅在下载它们的应用程序的生命周期内下载，例如 Web 浏览器。它们的优点是客户端没有安装任何东西;它们的缺点是每次需要时都会下载它们。由 `Extension-List` 标题下载的下载扩展名安装在下载它们的 JRE 的 `/ lib / ext` 目录中。它们的优点是它们在第一次需要时下载;随后它们可以在不下载的情况下使用但是，如本教程后面所示，部署它们会更复杂。

由于使用 `Class-Path` 标头的下载扩展更简单，我们首先考虑它们。例如，假设 `a.jar` 和 `b.jar` 是同一目录中的两个 JAR 文件，并且 `a.jar` 的清单包含此标题：

```
Class-Path: b.jar

```

然后 `b.jar` 中的类作为 `a.jar` 中类的扩展类。 `a.jar` 中的类可以调用 `b.jar` 中的类而不需要 `b.jar` 的类必须在类路径上命名。 `a.jar` 本身可能是也可能不是扩展名。如果 `b.jar` 与 `a.jar` 不在同一目录中，那么 `Class-Path` 标题的值应该设置为相对路径名 `b.jar` 。

正在扮演下载扩展的字符的类没有什么特别之处。它们被视为扩展，仅仅因为它们被其他 JAR 文件的清单引用。

为了更好地理解下载扩展如何工作，让我们创建一个并将其用于使用。

## 一个例子

假设您要创建一个使用上一节`RectangleArea`类的 applet：

```
public final class RectangleArea {  
    public static int area(java.awt.Rectangle r) {
        return r.width * r.height;
    }
}

```

在上一节中，您将 `RectangleArea` 类放入已安装的扩展中，方法是将包含它的 JAR 文件放入 JRE 的 `lib / ext` 目录中。通过使其成为已安装的扩展，您启用了任何应用程序以使用 `RectangleArea` 类，就好像它是 Java 平台的一部分一样。

如果您希望能够从 applet 使用 `RectangleArea` 类，情况会有所不同。例如，假设你有一个 applet，`AreaApplet`，它使用了类 `RectangleArea` ：

```
import java.applet.Applet;
import java.awt.*;

public class AreaApplet extends Applet {
    Rectangle r;

    public void init() {    
        int width = 10;
        int height = 5;

        r = new Rectangle(width, height);
    }

    public void paint(Graphics g) {
        g.drawString("The rectangle's area is " 
                      + RectangleArea.area(r), 10, 10);
    }
}

```

此 applet 实例化 10 `x` 5 矩形，然后使用 `RectangleArea.area` 方法显示矩形区域。

但是，您不能假设下载和使用您的 applet 的每个人都将在其系统上提供 `RectangleArea` 类，作为已安装的扩展或其他方式。解决该问题的一种方法是使 `RectangleArea` 类可以从服务器端获得，并且可以通过将其用作下载扩展来实现。

为了了解它是如何完成的，我们假设您已将`AreaApplet`捆绑在名为 `AreaApplet.jar` 的 JAR 文件中，并且类 `RectangleArea` 捆绑在 `RectangleArea.jar 中`。为了将 `RectangleArea.jar` 视为下载扩展， `RectangleArea.jar` 必须列在 `AreaApplet 的 `Class-Path` 标题中。 jar` 的清单。 `AreaApplet.jar` 的清单可能如下所示，例如：

```
Manifest-Version: 1.0
Class-Path: RectangleArea.jar

```

此清单中 `Class-Path` 标头的值为 `RectangleArea.jar` ，未指定路径，表示 `RectangleArea.jar` 位于同一目录中 applet 的 JAR 文件。

## 有关类路径标头的更多信息

如果 applet 或应用程序使用多个扩展名，您可以在清单中列出多个 URL。例如，以下是有效的标头：

```
Class-Path: area.jar servlet.jar images/

```

在 `Class-Path` 标题中，列出的所有未以' `/` '结尾的 URL 都是 JAR 文件。以“ `/` ”结尾的网址表示目录。在前面的示例中， `images /` 可能是包含 applet 或应用程序所需资源的目录。

请注意，清单文件中只允许一个 `Class-Path` 标头，并且清单中的每一行长度不得超过 72 个字符。如果需要指定多于适合一行的类路径条目，则可以将它们扩展到后续的连续行。以两个空格开始每个延续线。例如：

```
Class-Path: area.jar servlet.jar monitor.jar datasource.jar
  provider.jar gui.jar

```

未来版本可以消除仅具有每个标题的一个实例的限制，并且限制行仅限于 72 个字符。

下载扩展名可以是“菊花链”，这意味着一个下载扩展名的清单可以有一个 `Class-Path` 标题，引用第二个扩展名，可以引用第三个扩展名，依此类推。

## 安装下载扩展

在上面的示例中，applet 下载的扩展只有在加载 applet 的浏览器仍在运行时才可用。但是，如果小程序和扩展程序的清单中包含其他信息，则小程序可以触发扩展程序的安装。

由于此机制扩展了平台的核心 API，因此应明智地应用它。它很少适用于单个或一小组应用程序使用的接口。所有可见符号应遵循反向域名和类层次结构约定。

基本要求是 applet 和它使用的扩展都在其清单中提供版本信息，并且它们是签名的。版本信息允许 Java Plug-in 确保扩展代码具有 applet 期望的版本。例如， `AreaApplet` 可以在其清单中指定`最新`扩展名：

```
Manifest-Version: 1.0
Extension-List: areatest
areatest-Extension-Name: area
areatest-Specification-Version: 1.1
areatest-Implementation-Version: 1.1.2
areatest-Implementation-Vendor-Id: com.example
areatest-Implementation-URL: http://www.example.com/test/area.jar

```

`area.jar` 中的清单将提供相应的信息：

```
Manifest-Version: 1.0
Extension-Name: area
Specification-Vendor: Example Tech, Inc
Specification-Version: 1.1
Implementation-Vendor-Id: com.example
Implementation-Vendor: Example Tech, Inc
Implementation-Version: 1.1.2

```

applet 和扩展名都必须由同一个签名者签名。签署 jar 文件将就地修改它们，在其清单文件中提供更多信息。签名有助于确保只安装受信任的代码。签名 jar 文件的一种简单方法是首先创建一个密钥库，然后使用它来保存 applet 和扩展的证书。例如：

```
keytool -genkey -dname "cn=Fred" -alias test  -validity 180

```

系统将提示您输入密钥库和密钥密码。生成密钥后，可以对 jar 文件进行签名：

```
jarsigner AreaApplet.jar test
jarsigner area.jar test

```

系统将提示您输入密钥库和密钥密码。有关 `keytool` ， `jarsigner` 和其他安全工具的更多信息，请参见 [Java 2 平台安全工具摘要](https://docs.oracle.com/javase/8/docs/technotes/guides/security/SecurityToolsSummary.html)。

这是 `AreaDemo.html` ，它加载 applet 并导致下载和安装扩展代码：

```
<html>
<body>
  <applet code="AreaApplet.class" archive="AreaApplet.jar"/>
</body>
</html>

```

首次加载页面时，会告知用户 applet 需要安装扩展程序。随后的对话框会通知用户签名的 applet。接受两者都会在 JRE 的 `lib / ext` 文件夹中安装扩展并运行 applet。

重新启动 Web 浏览器并加载相同的网页后，仅显示有关小程序签名者的对话框，因为已安装 `area.jar` 。如果在不同的 Web 浏览器中打开 `AreaDemo.html` （假设两个浏览器使用相同的 JRE），也是如此。