在团队环境中使用 WebSphere Studio 进行插件开发
2009-12-18 00:00:00 来源:WEB开发网引言
插件的相关性以及与其有关的在团队中共享项目方式理解起来是比较复杂的。或许 Eclipse 的强大和深度意味着您学习起来会很费劲。本文将集中讨论在共享插件环境项目开发时会遇到的常见问题,以及如何利用 Eclipse 插件开发环境(PDE)。
本文从 Eclipse 插件框架和使用源代码储存库进行代码共享的概要开始,然后举例说明在跨团队共享插件代码时会出现的问题,例如在构建路径控制时。还将讨论环境的建立和如何最大程度的利用 IBM® WebSphere® Studio Application Developer V5.1.1 and V5.1.2 (以下称为 Application Developer)。这里讨论的内容同样适用于 Application Developer 所基于的 Eclipse 2.1 环境。Eclipse 的早期和晚期版本之间的差别将被提到 —— 要检查您的产品版本,请选择 Help =>About。
Eclipse 插件体系结构
Application Developer 以开放源代码 Eclipse 项目为基础。Eclipse 自身由多层 功能(一个功能就是一组插件)构成。 Eclipse 的功能强大之处远不止通过插件添加新的功能。它能按以前从未想到的方式扩展其他人员的贡献。这需要稳健的机制来声明和下载插件。以下将通过范例来讲述有关的细节。范例 shop 应用程序如下所示。这四个插件(日志、数据仓库、业务逻辑和用户接口)都包含一个可安装的功能:
图 1. 范例应用程序的插件关联结构
查看原图(大图)
在图框之间的箭头表示着插件之间的相关性(在核心 Eclipse 组件之间也同样存在相关性,例如 org.eclipse.ui )。每个插件在 清单( plugin.xml )文件中定义了它与库文件(.JAR 文件)和其他插件的相关性。在此关键的一点是类装载由 Eclipse 控制,并且每个插件拥有自己的类装载器。插件只能加载自身清单已定义的那些资源。
源代码储存库
Application Developer 提供了共享代码的多种方式;例如 Project Interchange Files。然而,在任何团队开发项目中,SCM (Software Configuration Management)或者如 CVS 的储存库是必需的,这样所有团队成员就能保持步调一致。Application Developer 对此提供了强大的功能(比如 Team 上下文菜单上的 Synchronize)。参见参考资料部分以获取与此主题有关的文章链接。
全部共享
在储存库中实现共享能带来丰厚的利益。理论上,对于每个插件,您将存储:
源文件(.java)
源数据文件(.classpath、plugin.xml、.project,以及其他类似文件)
单元测试文件 (数据和源代码)
引用的二进制库
构建文件(build.properties 或 build.xml)
为什么要进行尽可能多的检入(check-in)呢?主要有两大主要理由。第一,如果团队将共享最大化,那么能在系统之间变化的便所剩无几了。例如,通过共享构建文件可以减少由于在团队中封装方法的变更而导致的问题。问题已经浮出水面,特别是有关类路径的问题。我将在本文的后面将会处理其中的一些问题。
第二,储存库将提供版本支持。在使用现有的(或者第三方)库时会有极大的好处。例如,我的 com.example.shop.datastore 插件中的数据库。调试有关不相容的库之间出现的问题是很费时间的,而且这些问题可以通过版本控制显著减少。该想法可以推广到许多领域,包括:
已完成的插件/功能构建和环境详细信息
基本测试/构建脚本
项目/产品文档,许可证和类似资料
其他开发环境数据
可以共享的环境信息的例子是 Eclipse 首选项,例如在 Java™ 部分中的“Code Formatter”、“Editor Templates”和“Code Generation”部分。这些都在 Window =>Preferences 下可以找到,并且可以用 XML 方式导出。好处是可以共享代码标准,而且整个团队都能从这些灵活的 Java 编辑器选项中获益。
当然,细节部分会因存储数据方式的限制而变化。例如,对于存储文档、已完成的部分和其他构建的位置和方式,您的组织会有自己的约定。
解析插件的相关性
插件在自身的清单中定义了相关性。如以下摘要所示,图 1 中的 com.example.shop.ui 插件就依赖于 com.example.shop.log 和 com.example.shop.logic 。
<plugin
id="com.example.shop.ui"
...
<runtime>
<library name="ui.jar"/>
</runtime>
<requires>
<import plugin="org.eclipse.core.resources"/>
<import plugin="org.eclipse.ui"/>
<import plugin="com.example.shop.logic"/>
<import plugin="com.example.shop.log"/>
</requires>
...
PDE 自动估计要求类路径的库(参见 Preferences =>Plug-in development =>Java build path control)。在开发过程中,该数据存储在 .classpath 文件中。以下是有关 com.example.shop.ui 插件的范例:
<classpath>
<classpathentry kind="src" path="src/"/>
<classpathentry kind="var"
path="ECLIPSE_HOME/plugins/org.eclipse.core.resources_2.1.1/resources.jar" ... >
<classpathentry kind="src" path="/com.example.shop.logic"/>
<classpathentry kind="src" path="/com.example.shop.log"/>
...
核心 Eclipse 相关性 resources.jar 通过平台的 plugins 目录解析,而我的两个插件被解析为项目引用。该范例说明了 PDE 如何在清单中解析相关性来为 com.example.shop.ui 插件建立开发类路径。
提示:通过从带三角形图标的下拉菜单中选择 Filters 可以防止 Package Explorer 隐藏 .classpath 和其它点前缀的(dot-prefixed)文件。在该菜单中还有其他很多有用的选项。
共享项目
如果您想在人员和机器之间共享整个项目,有许多选项可以实现。请参见参考资料部分有关共享资源和 CVS 团队开发的文章。
在 Application Developer 中,在您从 CVS 检出(check out)或从文件系统导入一组项目之后,您将会发现一些构建错误。这些通常是未解析的插件或库(忽略代码问题)。在上文中 .classpath 范例中,可以发现它包含有关项目名称和插件库版本的特定条目。不幸的是,库版本随 Application Developer 版本的不同而有差别,如以下所示。另外,不能找到 com.example.shop.logic 插件是因为我在新工作区为该项目取了另外的名字。
图 2. 无效的插件库引用
查看原图(大图)
好消息是您可以告诉 Application Developer 进行自我修复!
修复已损坏的引用——更新类路径
要更新许多项目的类路径,右键单击 plugin.xml 文件或 Package Explorer 中的一组项目,并选择 Update classpath。在 Eclipse 的最新版本中,选择 PDE tools =>Update classpath同样可以更新 Dependencies 页面上插件清单编辑器中的单个插件类路径。然后,您需要根据构建首选项进行构建。
图 3 . 更新类路径以修复未解析的相关性
毫无疑问,在更新后,这些错误就肯定消失了。
提示:当您看见 The import **** cannot be resolved 信息出现在先前运行良好的环境中时,请不要尝试选择 Organize imports。当这些信息出现时,通常时因为找不到库而不是源代码有错误的导入语句。如果您在库不能进行解析时使用该指令,您最终将移除正确的导入,最坏的情况是,您将会获得那些有同样不合格名称的不正确的导入。
引用现有的二进制库(.JAR 文件)
假设您现有一个 Java 类的库(例如名叫 logger.jar ),而您的插件依赖这个库,那么您可以:
将 logger.jar 复制到每个使用该文件的插件中。
创建实用插件以封装 logger.jar 。
第一个选项是最简单的,但是不希望在项目周围出现许多库的副本——即使在版本控制下。因此使用第二个选项使其他插件通过日志插件来访问 logger.jar 会更好些。
在图 1 中, com.example.shop.log 插件提供了日志来支持其他插件。在插件项目和其他通常的 Java 项目之间一个很大的的区别是如何在完全部署好的配置中提供类路径。当插件安装好后,它的类装载器的类路径不是硬编码,而是当启动时基于 plugin.xml 文件由平台得出的。因此您必须在清单中声明库,因为无论如何 .classpath 文件都将被忽略。
图 4 . 在插件清单(plugin.xml)编辑器中引用现有的库
查看原图(大图)
来自 plugin.xml 清单的摘录展示了插件如何包含已编译的源代码(log.jar)和 logger.jar 库(保存在项目的 lib 子文件夹中的储存库中)。
<plugin
id="com.example.shop.log"
...
<runtime>
<library name="log.jar">
<export name="*"/>
<packages prefixes="com.example.shop.log,com.example.shop.log.actions"/>
</library>
<library name="lib/logger.jar">
<export name="*"/>
<packages prefixes="org.logco"/>
</library>
...
提示:为更快速的类装载指定包前缀(参见以上 plugin.xml 中< packages >部分)。
图 5 . Log 插件的 src 文件夹中的包和 lib/logger.jar 库
提示:将任何附加的文件(例如, lib/logger.jar )指定包含在插件导出中,并在 build.properties 文件编辑器中通过编辑 bin.includes 属性封装操作。这在您编辑 Runtime 页面是通常会更新。
提示:通常您必须强制更新类路径来解析清单中的库。参见上文中的“修复损坏的引用 -- 更新类路径”。
选择导出选项
我使用 Export the entire library 选项,这样其他的插件可以直接在 logger.jar 库中引用类。当其他插件的代码企图从 logger.jar 装载类时,将通过 com.example.shop.log 插件的类装载器对其进行解析(可以激活尚未激活的 Log 插件)。
提示:通过使用 Export using content filters 只导出必要的已发布资源给其他插件。这将导致类似于 <export name="org.logco.*"/> 的条目出现在 plugin.xml 中。
导出库的备选方案是为 logger.jar 库顶部的其他插件提供 facade。这样的接口可以使其他插件使用日志特征,而无须直接耦合到库,并提供更多的自由度来更改实现库,而不会干扰相关的插件。当然,这意味着需要更多的工作量以实现该接口。
混合二进制和源插件项目
如果您的项目或开发组中只有很好的插件(例如图 1 中所示),您将可能把它们都视为工作区中的标准源项目。Application Developer 将通过在平台中第一次搜索工作区中及外部的插件来解析插件的相关性(例如,解析 org.eclipse.core.resources )。
源项目 工作区中的标准 Eclipse 项目,包含编辑和构建的源代码。外部插件 通常是一组可用于您的开发环境的插件,例如 Application Developer 自带的插件在您的 ECLIPSE_HOME 目录中。
提示:使用 PDE 透视图中的 Plug-ins 视图来浏览外部插件。您可以使用选中插件的弹出式菜单来将插件添加到 Java 搜索机制。这使您可以浏览 Jar 并在 Open Type Hierarchy 对话框中查看类型。
然而,在开发组环境中,很多情况下您不希望每个插件都作为完整的源项目:
您有许多很少变动的插件,所以只需要作为二进制相关性。
开发组有大量的插件,每个成员只使用其中的一部分插件。
构建所有的插件源代码需要很长的时间。
当然,这些情况并不互相排斥,但它们表现的更像项目的依赖关系树。很有可能您将希望只编辑小部分插件,但依靠更大的插件组来进行构建和搜索。为此,Eclipse 有了二进制插件项目的概念。
二进制插件项目 工作区插件项目没有源文件夹,但其他方面却类似于正规的源项目。例如,它可以被浏览和搜索。
在下面的图 6 中,我将 Logging 插件安装到 Application Developer,这样当开发其他三个插件时,可以将其作为二进制组件使用。您也可以通过使用 Import =>External Plug-ins and Fragments 选项来创建二进制项目。参见参考资料中的文章“Put Eclipse features to work for you”,这篇文章描述了如何安装插件,而不会打乱您的产品安装目录。
图 6. 在 Plug-ins 视图中导入外部插件作为二进制项目
除了浏览很方便之外,使用基于外部插件的二进制项目的真正优点是它可以使类路径更加稳定。如果您看了“解析插件相关性”中的 .classpath 示例,您会发现工作区项目和外部插件的类路径条目的存储各不相同。实际上,类路径条目对于源项目和二进制项目来说是相同的,因为它们都是保存在工作区中。这意味者尽管有源项目和二进制项目的不同组合,开发人员也可以共享 .classpath 文件。
大型项目的插件类型组合范例
插件类型 | 建议的插件 |
源项目 | 被个别组件或在功能性组件中使用的少量插件。 |
二进制项目 | 通常被源项目浏览或使用的更大的插件组。这可能是项目或扩展 Eclipse 部分的更大的组件。 |
外部插件 | 项目的其他插件,以及平台上的插件。其中一些更相关的插件可以添加到 Java 搜索中。 |
提示:开启二进制项目标记 decorator 以使其区别于源项目 — 它们使用“01”decorator。参见图 7。使用 Window =>Preferences =>Workbench =>Label Decorations。
图 7. 在您的工作区中使用源项目和二进制项目
提示:使用 Package Explorer 下拉菜单中的 Filters 选项来显示或隐藏二进制项目。
提示:使用 Working Sets 来将插件项目组合为便于使用的类别。Working Sets 可以用来在 Package Explorer、Tasks 视图中过滤,并可用于一些操作。
使用动态类路径 —— 类路径容器
您可能会想与不同的项目配置相关的类路径是如何的复杂。如果 Application Developer 能够为您给出的设置测算 .classpath 文件,那么这里面的条目又有什么用呢?由于所有的内容都在运行时和开发时通过 plugin.xml 清单来驱动,环境难道不应该在后台完成这些工作吗?
不错,好消息是它确实可以。Application Developer V5.1.1 包含了容器管理类路径功能(在 Eclipse 2.1 和 Eclipse 3.0 缺省配置中可用),它解决本文描述的许多问题。使用该功能,类路径基于插件清单自动更新,不管您使用的是源项目、二进制项目还是外部插件,它都可以为您完成这些工作。
要使用该功能,选择 Plug-in development =>Java build path control preferences并选中 Use classpath containers。然后您将需要更新插件的类路径。
图 8. 为关联插件使用类路径容器
现在您可以监视每个插件所需库中的间接性级别。在 .classpath 文件 中,所有的库条目都与一个用于类路径容器的条目放在一起:
<classpath>
<classpathentry kind="src" path="src/"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="bin"/>
</classpath>
现在 PDE 将在内部用自动且可靠的方式管理工作区或外部的库。您可以在开发组中非常方便的共享那些 .classpath 和 .project 文件!
控制相关性
随着您的项目的进展,保持跟踪多个插件相关性将变得更加困难。为了对此进行帮助,Application Developer 可以:
查找未使用的插件相关性。
查找相关性所涉及的范围。
图 9. 估算相关性的使用
图 9 展示了 com.example.shop.ui 插件使用 com.example.shop.log 插件类的次数。该特征是非常有用的,因为您可以查看一个插件在其他插件中使用的深度。它能显示令人惊奇的结果。
Find unused dependencies选项提供了那些从未使用的插件完整的列表。减少不必要的相关性可以在运行时提供效率。
结束语
管理任何产品中的相关性都是一项艰难的工作。Eclipse 插件结构与其插件开发环境为构建复杂的标准组件的软件产品提供了强大的工具。Eclipse 解决了解析相关性带来的许多困难。但是学习掌握起来还是比较费劲的。使用 Eclipse 2.1 ,容器管理类路径功能可以保护开发人员避免不同配置的差别、灵活性的渐增以及设置的简单化而带来的问题。
在 Eclipse 3.0 中, 所有插件使用动态类路径。该功能以及其他新的功能将会使团队开发更加容易(参见页底 “参考资料” 中的 Eclipse.org 链接以获取更多相关信息)。
共享项目的开发环境可以为自身提供更多的时间用来开发代码。Application Developer 同样为您提供了调试、构建和测试插件的灵活的选择。请至“参考资料”部分以查阅有关跟踪、诊断运行时问题以及通过 Application Developer 使用 Ant 的相关文章。用正规的构建和测试来组合产品的开发设置将使您能够快速且平稳的进行插件项目开发。
更多精彩
赞助商链接