站内搜索: 请输入搜索关键词

当前页面: 开发资料首页Eclipse 专题使用 Update Manager 更新 RCP 应用程序

使用 Update Manager 更新 RCP 应用程序

摘要: Rich Client Platform,顾名思义,是一个构建富客户端应用的平台,基于 Eclipse的插件体系结构,由一系列所需要的最小插件集合所组成。一般来说,一个 RCP 应用程序在发布时有两种类型:基于插件(Plug-in)和基于功能部件(Feature)的。为了使用 Eclipse平台所提供的丰富功能(比如 Update,Web Start),我们必须开发基于功能部件的 RCP 应用。两者之间的转换也是非常容易的。这篇文章使用 Eclipse3.2 版本作为开发平台,提供了一个小型的 RCP 应用例程,并使用 Update Manager 来实现产品的自动更新。

简介

Eclipse RCP 是 Eclipse Platform 的一个子集(如图),从 Eclipse3.0 版本开始,Eclipse项目组对代码进行了重构,将 IDE 与 Workbench(工作台)彻底分离,实现了一个 Generic Workbench,使得基本的 RCP 应用中不再有 IDE 的影子。构成 RCP 的最小插件集合包括Runtime,OSGi,SWT,JFace,Workbench 等一些必须的部件,还有一些是可选部件(比如 Help, Update 等,如下图所示),所有这些插件使得我们的 RCP 程序可以完成绝大部分的企业应用需求。



Update 是 RCP 的一个可选部件,它的主要功能包括:

1)更新已经安装了的功能部件;

2)寻找新的功能并进行安装;

3)对已安装的功能部件进行配置。

这篇文章会围绕 Update 这个可选插件,使用 PDE 来开发一个具有自动更新功能的小型 RCP 应用程序。

建议读者先阅读下面的一些链接,以便对 RCP 有一个清晰的概念:

http://www.eclipse.org/articles/Article-RCP-1/tutorial1.html

http://www.eclipse.org/articles/Article-RCP-2/tutorial2.html

http://www.eclipse.org/articles/Article-RCP-3/tutorial3.html


<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td>
</td></tr></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tr align="right"><td>
<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>

开始

首先,我们需要一个插件,用来启动 RCP 应用,这个插件会包含基本的应用扩展点,请参考上面的链接。这里,我们使用 PDE 来创建一个 Eclipse 自带的具有一个视图(View)的例子程序。

启动 Eclipse,打开菜单File->New->Project, 选中Plug-in Project 并且键入工程名,比如 com.ibm.csdl.guardian.examples.。在下一页中,填写此插件的基本属性信息,对于问题"Would you like to create a rich client application?" 选择Yes. 最后,使用所提供的模板 "RCP application with a view" 并接受缺省设置来创建一个RCP的插件工程。



浏览插件配置文件plugin.xml, 我们会发现PDE创建了一个application的扩展,这个扩展将会作为RCP应用的程序入口,并且会被另外一个扩展:Product所使用(见本文产品部分)。


<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td class="code-outline">


 


</td></tr></table>

<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td>
</td></tr></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tr align="right"><td>
<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>

功能部件

为了使用应用程序的更新功能,我们必须为RCP定义一个或多个功能部件(Feature)。打开菜单File->New->Project, 选中 Feature Project 并且键入工程名称,比如 com.ibm.csdl.guardian.examples.feature。在下一页,选中刚才所创建的插件工程: com.ibm.csdl.guardian.examples,作为此功能部件所包含的插件。

对于Eclipse3.2版本,一个可执行的RCP应用至少应包含下面的这些插件(Windows平台):

com.ibm.icu,
org.eclipse.core.commands,
org.eclipse.core.contenttype,
org.eclipse.core.expressions,
org.eclipse.core.jobs,
org.eclipse.core.runtime,
org.eclipse.equinox.common,
org.eclipse.equinox.preferences,
org.eclipse.equinox.registry,
org.eclipse.help,
org.eclipse.jface,
org.eclipse.osgi,
org.eclipse.swt,
org.eclipse.swt.win32.win32.x86,
org.eclipse.ui.forms,
org.eclipse.ui.workbench,
org.eclipse.ui.

并且,为了使用RCP应用程序的更新功能,还需要包含下面的几个插件:
org.eclipse.update.configurator,
org.eclipse.update.core,
org.eclipse.update.ui.

所以,同时选中这些插件来完成功能部件工程的创建。



最后,键入一个更新站点的URL和站点名称,Update Manager会使用这些信息来连接一个或多个更新站点。在这里,URL既可以使用网络地址,也可以使用本地的文件系统地址。下面是功能部件的配置文件feature.xml的典型内容:


<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td class="code-outline">

[Enter Feature Description here.]


[Enter Copyright Description here.]


[Enter License Description here.]



</td></tr></table>

<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td>
</td></tr></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tr align="right"><td>
<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>

包装成产品

RCP应用程序在启动时,需要一个application的扩展点或一个product的扩展点作为入口。同时,为了简化RCP应用程序的打包过程,我们使用一个产品配置文件来对例子程序进行设置。其中product 扩展点是基于application扩展点的。

在PDE的Package Explorer视图中, 选中刚才所创建的RCP插件工程,打开菜单 File->New->Product Configuration,键入一个产品配置文件名称,比如examples.product ,并且使用缺省设置来完成产品配置的创建工作。

在产品配置编辑器(product configuration editor)中,指定产品名称,比如examples。点击New按钮,使用缺省设置或指定一个产品标识,在RCP启动时会使用这个ID作为应用程序的入口。特别地,对于产品配置类型,要选择基于功能部件(features),否则无法使用更新功能。概览(Overview)页内容大致如下图所示:



切换到配置页,将我们的功能部件com.ibm.csdl.guardian.examples.feature 添加到部件列表中。如果必要,可以对其它页的属性信息进行更改,这里我们使用缺省值。最后,在插件配置文件plugin.xml中,添加product扩展:


<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td class="code-outline">



</td></tr></table>

现在,我们可以切换到概览页,点击 "Launch the product" 来测试我们的RCP应用:




<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td>
</td></tr></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tr align="right"><td>
<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>

Update Manager

这只是一个很简单的RCP应用,我们可以在此基础上添加透视图及视图以实现各种各样的功能,但这些不是本文的重点,请参考其它资料。这里,我们将在此应用的基础上添加软件更新功能。

添加更新菜单

首先,应该有一种方式,用来呼叫出更新管理器,我们使用菜单来实现这个功能。在类 ApplicationActionBarAdvisor中,修改 makeActions 方法,,添加一个Update Action:


<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td class="code-outline">
        …
exitAction = ActionFactory.QUIT.create(window);
register(exitAction);

updateAction = createUpdateAction(window);
register(updateAction);
        …

        
</td></tr></table>

修改 fillMenuBar 方法,将Update菜单添加到Help主菜单下:

… MenuManager helpMenu = new MenuManager("&Help",IWorkbenchActionConstants.M_HELP); menuBar.add(helpMenu); helpMenu.add(updateAction); …

实现软件更新功能

在类 UpdateAction 中,实现 run 方法如下:


<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td class="code-outline">
BusyIndicator.showWhile(window.getShell().getDisplay(), new Runnable() {
    public void run() {
      UpdateJob job = new UpdateJob("Search for update", false, false);//$NON-NLS-1$
      UpdateManagerUI.openInstaller(window.getShell(), job);
      PlatformUI.getWorkbench().getProgressService().showInDialog(window.getShell(), job);
}
});
</td></tr></table>

记得将 ore.eclipse.update.ui 这个插件添加到com.ibm.csdl.guardian.examples 插件的所需插件列表中,否则上面的类将不能通过编译。

好了,我们的RCP应用已经具备了软件更新功能!是不是感觉很简单?是的,Eclipse平台一个优美的地方就是将很多功能部件都设计成为一个Framework,具有很高的可重用性,用户只需做很少量的工作就能实现很复杂的功能,Eclipse的Update Manager就是一个很好的例子。再次启动我们的RCP应用,已经可以使用软件更新功能了,如下图。不过,因为更新站点并没有准备好,所以不会发现新的版本,下面会详细介绍这方面的内容。



打包RCP应用

到目前为止,这个例子程序一直是作为一个Eclipse的运行时应用来运行的,我们需要将其打包到Eclipse之外,形成一个单独的可执行的应用程序。得益于Eclipse的插件体系结构,打包的过程将非常简单。当然,我们可以自己编写脚本代码去完成这个步骤,但是在PDE中,提供了一个导出工具,使得我们可以更加方便的实现这个过程。首先确认插件工程下的build.properties文件包含了所有必需的资源文件,因为PDE的导出向导将会使用Ant并读取这个配置文件来对每个插件进行打包工作。

现在使用产品配置编辑器打开examples.product文件,切换到概览页,点击 "Eclipse Product export wizard" ,弹出导出向导配置窗口。使用 examples.product 作为配置文件并键入应用程序的主目录,比如ExampleRCP,PDE在打包时将会创建这个应用程序的根目录。另外,建议将"Synchronize before exporting"选中,以便在打包时检查配置文件是否与所包含的插件相匹配。最后,指定存放此RCP应用的目的文件夹并开始导出过程:



现在,我们可以进入刚才所指定的目的文件夹,通过双击可执行文件(在Launcher页进行配置)来启动应用程序。

准备新版本

假设一下产品已经发布出去,但是客户却想在树上显示四个节点,我们使用Update Manager来实现这个新的需求。

首先,需要在类View 中更改源代码:


<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td class="code-outline">
…
public Object[] getElements(Object parent) {
// add the fourth node to satisfy the customer's new requirement.
return new String[] { "One", "Two", "Three", "Four" };
}
…
</td></tr></table>

下一步需要创建一个更新站点的工程。打开菜单 File->New->Project,选择 Update Site Project,并且为此工程指定一个名称,比如com.ibm.csdl.guardian.examples.site.

在站点清单编辑器中,切换到Site Map页面,将不同的功能部件切分为类别。在Archives页面,设定更新站点的URL及描述信息,URL可以使用本地文件系统,或其它网络协议,比如HTTP等。为了方便测试,这里我们使用本地文件系统目录作为更新站点。



文件site.xml 最终的样子:


<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td class="code-outline">

   
     Examples RCP Application Update Site
   
   
         
    
    

</td></tr></table>

在新版本编译通过之后,修改RCP应用包含的所有插件及功能部件的版本号,确保比发布给客户的版本要高(不要修改插件的ID),以表示有更新版本可用。

在插件com.ibm.csdl.guardian.examples 的MANIFEST.MF文件中:


<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td class="code-outline">
Bundle-Version: 1.0.1
…
</td></tr></table>

在feature.xml文件中:


<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td class="code-outline">
</td></tr></table>

因为我们在功能部件的配置中使用了缺省设置 "Synchronize versions on build" ,所以PDE的打包工具会自动为所生成的二进制Jar文件生成正确的文件名以显示新的版本号。

现在的site.xml 文件内容:


<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td class="code-outline">

    
       Examples RCP Application Update Site
    
   
      
   
   

</td></tr></table>

在站点清单编辑器的Site Map页面中,选中所要更新的功能部件并且点击 "Build" ,PDE会在此站点工程目录下生成所需要的更新功能部件及插件。将文件site.xml,目录features 和plugins 拷贝到feature.xml中所指定的URL(在这里是本地文件系统), 再次启动我们的例子RCP应用,现在即可以使用"Find and Install"菜单来对产品进行更新:



点击Next,会出现许可证描述信息(在feature.xml指定),只有选择接受许可证之后,下载更新包及安装过程才会继续:



下载并安装完毕之后,会提示重新启动RCP应用,这时即可以看到软件更新之后的效果:



自动更新

为了使更新过程更加智能,Update Manager还支持软件的自动更新,并提供了很多选项来对更新时间进行设置。我们所需要做的很简单,只需要将插件 org.eclipse.update.scheduler 添加到 feature.xml 的插件包含列表中并添加一个菜单来呼叫出自动更新的配置项页面:


<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td class="code-outline">

…
preferencesAction = ActionFactory.PREFERENCES.create(window);
register(preferencesAction);
…
MenuManager windowMenu
= new MenuManager ("&Window", IWorkbenchActionConstants.M_WINDOW);
menuBar.add(windowMenu);
windowMenu.add(preferencesAction);
…
</td></tr></table>

从这里可以看出,Update Manager 使用org.eclipse.ui.preferencePages 这个扩展来对更新选项进行配置:



配置完成后,当更新条件满足时,RCP会自动弹出一个窗口,提示用户是否存在新的版本可用并进行安装。



有一点需要注意: 在更新到新的版本后(其实是下载新版本的插件Jar包),老版本的Jar 文件不会被自动删除,因为有时更新会出现问题,用户还可以再使用老的版本。对于这个问题,请参考下面这个链接来得到更多信息: https://bugs.eclipse.org/bugs/show_bug.cgi?id=70990.

管理所安装的功能部件

一个大型的企业级RCP应用通常会包含大量的功能部件,如果有的功能部件暂时不会被使用,刚可以将其置为不可用状态,这样既可以加速应用程序的启动过程,也会对RCP应用的性能有所提高。Update Manager也提供了这个功能,我们的例子程序使用一个菜单来呼叫出管理窗口:


<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td class="code-outline">
…
manageAction = createManageAction(window);
register(manageAction);
…
MenuManager helpMenu = new MenuManager("&Help", IWorkbenchActionConstants.M_HELP);
helpMenu.add(manageAction);
…
</td></tr></table>

在类 ManageAction 中,实现 run 方法如下:


<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td class="code-outline">
BusyIndicator.showWhile(window.getShell().getDisplay(), new Runnable() {
public void run() {
UpdateManagerUI.openConfigurationManager(window.getShell());
}
});
</td></tr></table>

当点击此菜单后,即会弹出产品配置窗口,可以方便的管理所安装的功能部件:




<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td>
</td></tr></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tr align="right"><td>
<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>

结论

使用Update Manager不仅可以方便的给RCP应用程序添加软件更新功能,还可以对所安装的功能部件进行方便的管理。得益于Update Manager的框架结构(其它Eclipse的组件也是如此),我们还可以利用其所提供的API,对产品的更新功能进行定制,使得产品具有自己的特色。



<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td>
</td></tr></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tr align="right"><td>
<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>

下载

<table width="100%" class="data-table-1" cellspacing="0" cellpadding="0" border="0"><tr><th>名字</th><th align="right">大小</th><th>下载方法</th></tr><tr><td nowrap="nowrap">updatemanager.zip</td><td align="right" nowrap="nowrap">27KB</td><td nowrap="nowrap">HTTP</td></tr></table><table cellspacing="0" cellpadding="0" border="0"><tr valign="top"><td colspan="5"></td></tr><tr><td></td><td>关于下载方法的信息</td><td></td><td></td><td>Get Adobe® Reader®</td></tr></table>

参考资料

  1. 更多 Eclipse 内容请参考 Eclipse 专题
  2. Eclipse.org Articles. Eclipse.org.
  3. Eclipse Online Help. Eclipse.org.
  4. Eclipse Rich Client Platform-Designing, Coding, and Packaging Java Applications. Jeff McAffer, Jean-Michel Lemieux.


关于作者<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td colspan="3"></td></tr><tr align="left" valign="top"><td>

</td><td></td><td width="100%">

马吉荣,IBM中国软件开发中心DB2 II Team,软件工程师,现主要从事GUI Test Automation的框架研究及开发,DB2相关产品的测试工作。研究兴趣包括Eclipse,MDA,XML及数据库等相关领域。联系方式:majirong@cn.ibm.com.

</td></tr></table>



↑返回目录
前一篇: 探索 Eclipse 的嵌入式富客户端平台
后一篇: IBM WebSphere 开发者技术期刊: 为 WebSphere 平台部署 Eclipse 富客户端应用程序