级别: 中级 Chris Aniszczyk (zx@us.ibm.com), 软件工程师, IBM
2008 年 3 月 17 日 Eclipse 中的插件开发有一点点类似于一种艺术形式。如果刚开始接触插件概念(尤其是在 OSGi 和 Eclipse 环境中),学习使用 Eclipse 配备的帮助编写插件的多种工具可能非常麻烦。本文的目的旨在帮助您了解一些基本插件开发技巧,并附带介绍了一些最佳实践。
“插件开发 101” 系列文章主要介绍如何开发插件。但是在开始之前,需要确保配备开发插件所需的正确环境。第一步是从 Eclipse.org 下载带有 Plug-in Development Environment (PDE) 的 Eclipse 发行版。建议下载最新版本的 Eclipse Classic。在本系列中,我们将使用 Eclipse V3.4 (M5) 的里程碑发行版。完成后,就准备好开发插件了(如果您刚开始使用 Eclipse,要了解查找 Eclipse 及附加背景信息的位置,请查阅 参考资料)。
为了使插件开发更易于理解,本文将遵循图 1 中显示的工作流程。在本系列的第 1 部分中,我们将主要介绍工作流程的前五个步骤。我们将把最后两个步骤留给第 2 部分,第 2 部分将主要介绍富客户机应用程序。
图 1. 插件开发工作流程
 |
OSGi 业务的含义是什么?
从 V3.0 开始,Eclipse 通过使用 OSGi 替换先前版本中不稳定的 Eclipse 插件技术,实现了一次巨大飞跃。OSGi Alliance 是一个独立的、非盈利性组织,负责 OSGi 技术,类似于 Eclipse Foundation 的职能。OSGi Alliance 负责制定描述 OSGi 技术的规范。简言之,OSGi 技术为应用程序开发提供了一种面向服务的基于插件的平台。各种实现都是基于这些规范的。最常见的一个实现是 Equinox,它是 Eclipse 的规范实现(有关背景信息,请参阅 参考资料)。 |
|
在详细了解如何创建插件之前,让我们先讨论插件到底是什么。从技术上讲,插件是自包含(self-contained)和自描述(self-describing)的 Java™ Archive (JAR)。它是自包含 的,因为它保存插件运行所需的代码和资源。它是自描述 的,因为它包括描述插件定义、要求从外界获得的输入和具备的功能的信息。在插件中,您一般会看到两个描述符文件:MANIFEST.MF 和 plugin.xml。
首先进行创建
插件开发工作流程的第一部分涉及创建一个插件项目。在 Eclipse 中,这可以通过选择 New >Project... 菜单项来轻松完成。在显示的向导中,选择 Plug-in Project 作为需要创建的项目类型。
图 2. New Plug-in Project 向导
就像任何其他 Eclipse 项目一样,向导将要求您选择项目名称。建议选择 helloworld。还有一个选择目标平台的选项。此上下文中的目标平台只意味着是要针对 Eclipse 版本,还是要针对诸如 Equinox 之类的 OSGi 框架。在本例中,为简单起见,我们的目标平台是 Eclipse 3.3 版。New Plug-in Project 向导的下一页主要关于插件内容。
图 3. 插件内容
在插件内容向导页面中,我们必须完成一张表单才能使插件与 Eclipse 兼容。插件标识符是表示插件的惟一标识符的字段。任何其他插件都不能共用相同的标识符。插件版本是由分别命名为 major.minor.service.qualifier 的四个部分(三个整数和一个字符串)组成(要获得 Eclipse 插件版本化指南,请参阅 参考资料)。插件名称仅表示一个人类可读的名称。插件提供者字段是一个人类可读的字符串,表示插件的作者。简单地说,执行环境 (EE) 字段表示包能够在其中运行的最低 JRE 版本(请参阅 参考资料)。
向导将给我们提供用于生成插件激活器的选项。插件激活器只是用于控制插件生命周期的类(可将其视为一种启动和停止方法)。通常,激活器负责在不再需要插件时设置和正确处理资源。在本文的示例中,我们需要使用一个激活器,这是对 UI 有用的插件;而且我们要创建 Rich Client Platform (RCP) 应用程序(请参阅 参考资料)。
创建插件的最后一步涉及选择以其为基础创建新插件的模板(参见图 4)。如果非常熟悉插件的创建,通常可以跳过此步骤。但是,初学者需要有一个入门过程,因此 Eclipse SDK 附带了许多模板来帮助您快速入门。在本例中,我们选择带有一个视图的基本的 Hello World 应用程序。
图 4. 插件模板
修改
 |
MANIFEST.MF 内部
如果您对 MANIFEST.MF 文件中的各个可用文件头感兴趣,请阅读可以从 OSGi Alliance 获得的 OSGi 规范(请参阅 参考资料)。 |
|
在完成上一步后,已在工作空间中创建了一个新插件。现在有一个编辑器(参见图 5)可帮助处理这个新插件。我们看到的编辑器中的第一页是 Overview 页面,该页面包含可修改的插件标识符信息以及描述可以在插件内编辑的各个条目的信息。例如,我们看到先前使用图 4 中所示的模板定义的标识符 (ID) 和版本字段。
图 5. 插件编辑器(Overview 页面)
扩展和扩展点
 |
丰富的扩展点
从 Eclipse V3.3 之后,可以在 Eclipse SDK 中找到 200 多个扩展点。要查看 SDK 中可扩展内容的列表(即扩展点),请参阅 Eclipse Foundation 中标题为 “Platform Extension Points” 的文档(请参阅 参考资料)。 |
|
插件开发的下一步涉及添加扩展。但是,在了解详细信息之前,让我们先来了解开发可扩展 Eclipse 插件时涉及的两个重要主题:扩展和扩展点。使用一个简单的类比,您可以把扩展 视为插头并把扩展点 视为插座。每个扩展点都是惟一的并且定义需要遵守的契约。例如,Eclipse 将附带 org.eclipse.ui.editors 扩展点(插座),它允许提供我们自己的编辑器(插头)。
在本例中,我们将创建一个添加到 Eclipse 工具栏中的新扩展。为了完成此步骤,我们将对 org.eclipse.ui.actionSets 扩展点使用模板(类似于创建插件时使用的模板)。在插件编辑器的 Overview 页面的 Extension/Extension Point Content 部分中,请选择 Extensions 链接。单击 Add...,然后选择填充了所有默认值的 org.eclipse.ui.actionSets 模板(参见图 6)。
图 6. 扩展模板
运行时
插件的重要部分是它的自描述性。插件必须描述它所提供的功能。在 Eclipse 环境中,这称为导出包。在插件中,我们可以决定导出哪些包,以便其他插件可以在这些包中查看是否要与我们的插件建立依赖关系。还可以把导出的包标记为内部包,这将告诉插件开发人员我们不把这个包视为 API。要指定导出包,需要使用 manifest 编辑器中的 Runtime 页面。
图 7. Runtime 页面
依赖关系
 |
丰富的插件
Eclipse 生态系统中有大量可以利用的插件,因此很有可能会有遗漏。在搜索插件时建议从下面两个站点开始:第一个站点是 Eclipse Foundation 的项目列表,第二个站点是 Eclipse Plug-in Central (EPIC)(请参阅 参考资料)。 |
|
在上一节中,我们描述了插件必须完成哪些操作才能向外界公开其功能。假定您是一个不同的插件并且想要使用前述功能。您将如何表达这类意图?在 Eclipse 环境中,这叫做依赖关系。在最简单的情况下,插件可以与其他插件存在依赖关系。例如,如果需要在 Eclipse 中构建您自己的编辑器,则需要依赖于 org.eclipse.ui.editors 插件。要指定依赖关系,需要在插件编辑器的 Dependencies 页面中完成。
图 8. Dependencies 页面
注意,除了与单个插件建立依赖关系,还可以选择与从插件导出的包建立依赖关系(请参阅 Dependencies 页面中的 Imported Packages 部分)。这是一个更高级的主题,并且在不需要把您的插件与特定实现绑定在一起时十分有用。例如,假定与提供 XML 解析器的 com.company.xml.parser 包之间存在依赖关系。现在想象有两个诸如 com.company.xml.parser.mobile 和 com.company.xml.parser.desktop 之类的插件,这两个插件提供了相同 XML 解析器的针对不同环境的两个不同实现。
源代码编辑器
Runtime 页面和 Dependencies 页面只是 MANIFEST.MF 文件主要内容的可视化表示。对于需要手动编辑此文件源代码的高级用户,PDE 提供了一个源代码编辑器,其中提供了针对插件清单定义中的各种文件头的代码完成功能。
图 9. 编辑源代码
测试和调试
插件开发的下一步涉及测试和调试。要测试插件,Eclipse 和 PDE 有一个自托管 (self-hosting) 概念。自托管 表示我们能够启动一个新的 Eclipse,其中带有目前正在工作空间中开发的插件,而不必实际导出或部署任何插件。要启动新 Eclipse,您需要做的只是通过 Overview 页面的 Testing 部分来启动另一个运行时工作台(请参阅 Overview 页面中的 Launch an Eclipse application 链接)。几秒钟后,您将看到弹出一个新工作台,在工具栏中可以看到插件的样例操作。
图 10. Eclipse 中的自托管
 |
由测试驱动的插件开发
在实际开发插件前,如果您希望从测试开始,则可以创建一个只包含测试的插件项目。有一个称为 Plug-in JUnit Test 的特殊启动配置可以运行插件内包含的测试。 |
|
要在调试模式下启动自托管插件,只需在 Overview 页面的 Testing 部分中单击 Launch an Eclipse
application in debug mode 链接。要实际调试插件,需要设置相关的断点。如果您刚开始学习在 Eclipse 中进行调试,建议查阅 developerWorks 文章 “Debugging with the Eclipse Platform” 来帮助您开始工作(请参阅 参考资料)。
要设置关于启动或调试插件的更详细选项,请转到启动配置对话框,您可以使用 Run > Run Configurations... 菜单项调用该对话框。插件的相关启动配置类型称为 “Eclipse Application”,因为我们要启动的内容实际上是一个 Eclipse 应用程序(参见图 11)。在启动配置内,您可以设置诸如参数之类的内容,并且可以控制使用哪个 JRE 启动应用程序。
图 11. 启动配置对话框
把字符串外部化
插件开发中的一个常见步骤是国际化。如果您的插件非常有用并且将由多方测试,则通常要求确保插件能够在不同语言中运行。幸好,把与插件相关的字符串外部化所需的工作量非常少。在 PDE 中,可以通过右键单击插件的 Overview 页面并选择 Externalize Strings... 菜单项调用一个向导。做出选择后,系统将显示这个向导,该向导将显示与外部化相关的所有字符串。
图 12. Externalize Strings 向导
实际上,这样做仅仅是为插件生成一个 plugin.properties 文件(包含外部化字符串),并把 Bundle-Localization 文件头添加到 MANIFEST.MF 文件中。Bundle-Localization 文件头只允许您为外部化字符串定义名称和可选位置。在本例中,Bundle-Localization 是 “插件”,这表示各种语言环境的字符串都将位于诸如 plugin.properties(参见图 13)、plugin_fr.properties 或 plugin_de.properties 之类的文件中。文件名中下划线后的内容表示语言环境。
图 13. plugin.properties 文件
就是这样!这就是开始国际化插件时涉及到的全部内容。有关更多信息,建议阅读 Eclipse corner 中较旧但仍然有意义的文章:“如何国际化 Eclipse 插件” 和 “如何测试国际化后的 Eclipse 插件”(请参阅 参考资料)。
组织清单
开发之旅的下一步是通过一些最佳实践来组织清单文件(即 MANIFEST.MF 和 plugin.xml)。PDE 提供了一个通过 Overview 页面的 Exporting 部分可以调用的便利向导。向导启动后(参见图 14),将为您提供各种可以调整的选项。默认值都十分合理,但是某些选项需要确保 plugin.properties 文件中没有散乱的键,这非常有用。
图 14. Organize Manifests 向导
结束语
大体上,本文的任务是介绍插件开发的基础知识,并附带介绍一些最佳实践。我们通过创建一个样例插件并完成一个典型插件开发工作流程介绍了前述内容。了解了工作流程后,开发插件将变得较为轻松,而且用诸如 Organize Manifests 向导之类的最佳实践维护这些插件甚至更轻松。第 2 部分将主要介绍如何使用富客户机应用程序开发工具以及如何完成图 1 中所示的插件开发工作流程的剩余部分。
参考资料 学习
获得产品和技术
讨论
关于作者  | 
|  | Chris Aniszczyk 是 IBM Lotus 的 Eclipse 提交者,专门从事 OSGi 相关的开发工作。他近期的主要目标是改进 Eclipse 的 Plug-in Development Environment (PDE) 并且在 IBM Lotus 组织内部宣传使用 Eclipse。他是开放源码的忠实拥护者,热衷于对开放源码的推广。他在自己的博客中传播 Eclipse,并且他还是 Eclipse Foundation 理事会的 Eclipse 提交者荣誉代表。他十分乐意与您讨论关于开放源码和 Eclipse 方面的问题。 |
对本文的评价
|