注意:更新管理器仍在开发中,可能在获得稳定版本之前还会作些更改。在现阶段提供它的目的是为了获取早期使用者的反馈,因为我们知道添加机制的具体细节可能会断断续续地进行更改。 |
介绍
方案
封装约定
概念
组件归档文件
配置归档文件
转换封装信息
安全注意事项
封装 NL
封装特定于目标的支持
封装支持可交付件
安装结构
完全安装与参考安装
文件系统映射:完全安装
工作区文件
文件系统映射:参考安装
启动 Eclipse
更新注意事项
更新非平台组件
更新平台
更新 JRE
更新产品文件
更新启动支持
从更新故障中恢复
从错误更新中恢复
安装清理
不受管 Eclipse 功能
安装注意事项
新安装
合并安装
特定于平台的注册
开发注意事项
安装位置独立性
本机可执行文件
并行插件版本支持
版本迁移
在开发(也就是说,频繁地更改)插件期间,其内部文件结构会反映怎样做对开发者最方便。这一般取决于正在使用的特定开发工具。然而,开发者通常很可能会将插件设置为从包含公开的 .class 文件的目录树执行,而不是从 .jar (需要额外的步骤来创建该 .jar,而开发者都讨厌额外的步骤)执行。而且, 在此阶段中,开发者不用特别留意插件设置版本信息,因插件是在不断变化的。
然而,当准备好要封装插件时,需要将它转换为适合于进行封装和安装的格式。这通常意味着创建运行时 .jar 并除去任何开发期文件(源文件以及公开的 .class 文件等等)。这还意味着用正式的插件版本更新 plugin.xml 清单并反映插件目录名中的版本(有关详细信息,参见“并行插件版本支持”)。
插件段
插件段(或就称为段)允许将基本插件的某些方面独立封装。这包括(但可以不限于)
插件、特定于操作系统或特定于窗口系统的代码或供备用用户使用的插件内容
(如随插件一起提供的 SDK 开发者信息)的已转换资源。在运行时,段被逻辑地合并到基本插件中。从封装的角度来看,允许将段与基本插件物理地封装在一起,或独立地封装和处理这些段。例如,允许创建“语言包”或独立于基本功能分发的特定“操作系统包”。
组件
组件通常是包含某些用户功能的一组插件和/或插件段。可将组件作为封装和安装过程的一部分公开给用户,因为组件表示一个功能选择单元。组件还表示一个安装单元(将所有被包含文件一起安装在一个安装树中)。组件具有版本标识符。
组件封装为一个 Java .jar,且包含必须的插件、插件段和组件安装清单(xml 文件)。可由 Eclipse 更新管理器将组件 .jar 置于更新服务器上以供下载和安装,或使用其中一种“传统的”安装程序技术将组件 .jar 用作正式封装过程的输入。将在稍后描述组件 jar 及其安装清单的格式。
配置
配置是用于一组设置了版本的组件的设置了版本的分组机制。例如,可使用它来指定作为产品的特定版本构建和测试了哪个组件配置。
配置封装为 Java .jar,且包含配置安装清单(xml 文件)。清单包含对构成配置的组件的引用,并包含安装和版本更新约束。注意,配置 .jar 不实际包含组件文件(而只包含引用)。
可由 Eclipse 更新管理器将配置 .jar 置于更新服务器上以供下载和安装,或使用其中一种“传统的”安装程序技术将配置 .jar 用作正式封装过程的输入。将在稍后描述配置 jar 及其安装清单的格式。
当前的 Eclipse 实现不允许嵌套配置。
名称的格式为
<componentId>_<version>
例如,
org.eclipse.platform_1.0.3.jar
com.ibm.tools.jspeditor_3.1.0\install.xml
组件 jar 具有下列内部路径结构:
install/
components/
<componentId>_<version>/
install.xml
(其他可选文件)参见“转换封装信息”
plugins/
<pluginId>_<pluginVersion>/
plugin.xml
(其他插件文件)
fragments/
<fragmentId>_<fragmentVersion>/
fragment.xml
(其他段文件,可能还包括 plugin.xml)
该 .jar 就包含一个 install/components/ 路径,当中只有一个 install.xml 文件。在其相对目录(具有版本标识符)中包含零个或更多个插件。另外,其相对目录(具有版本标识符)包含零个或更多个插件段。它还包含由 Java jar 实用程序生成的 meta-inf/ 目录。
组件 install.xml 格式由下列 dtd 定义:
<?xml encoding="US-ASCII"?>
<!ELEMENT component (description?, url?, plugin*, fragment*)>
<!ATTLIST component
label CDATA #IMPLIED
id CDATA #REQUIRED
version CDATA #REQUIRED
provider-name CDATA #IMPLIED
>
<!ELEMENT description (#PCDATA)>
<!ELEMENT url (update*, discovery*)>
<!ELEMENT update EMPTY>
<!ATTLIST update
url CDATA #REQUIRED
label CDATA #IMPLIED
>
<!ELEMENT discovery EMPTY>
<!ATTLIST discovery
url CDATA #REQUIRED
label CDATA #IMPLIED
>
<!ELEMENT plugin EMPTY>
<!ATTLIST plugin
label CDATA #IMPLIED
id CDATA #REQUIRED
version CDATA #REQUIRED
>
<!ELEMENT fragment EMPTY>
<!ATTLIST fragment
label CDATA #IMPLIED
id CDATA #REQUIRED
version CDATA #REQUIRED
>
元素和属性定义如下所示:
名称的格式为
<configurationId>_<version>
例如,
org.eclipse.sdk_1.1.5.jar
com.ibm.wsa_1.0.1\install.xml
配置 jar 具有下列内部路径结构:
install/
configurations/
<configurationId>_<version>/
install.xml
(其他可选文件)参见“转换封装信息”
(“产品”文件)参见“启动 Eclipse”
该 .jar 就包含一个 install/configurations/ 路径,当中只有一个 install.xml 文件。它还包含由 Java jar 实用程序生成的 meta-inf/ 目录。
配置 install.xml 格式由下列 dtd 定义:
<?xml encoding="US-ASCII"?>
<!ELEMENT configuration (description?, url?, component*)>
<!ATTLIST configuration
label CDATA #IMPLIED
id CDATA #REQUIRED
version CDATA #REQUIRED
provider-name CDATA #IMPLIED
application CDATA #IMPLIED
>
<!ELEMENT description (#PCDATA)>
<!ELEMENT url (update*, discovery*)>
<!ELEMENT update EMPTY>
<!ATTLIST update
url CDATA #REQUIRED
label CDATA #IMPLIED
>
<!ELEMENT discovery EMPTY>
<!ATTLIST discovery
url CDATA #REQUIRED
label CDATA #IMPLIED
>
<!ELEMENT component EMPTY>
<!ATTLIST component
label CDATA #IMPLIED
id CDATA #REQUIRED
version CDATA #REQUIRED
allowUpgrade (true | false) "false"
optional (true | false) "false"
>
元素和属性定义如下所示:
label="%cfg Eclipse SDK for Linux"
将导致以键“cfg”来在正确特性文件中查找资源。若未提供任何特性文件,或未找到键,则使用缺省字符串值(在 %key 后面)。
使用 Java 资源绑定命名约定将特性文件命名为 install_<locale>.properties。在组件 .jar 和配置 .jar 中,这些特性文件被放置在它们的相应 install.xml 文件所在的目录中。
访问资源绑定时,代码可选择清单的适当 NL 变体(通过使用查找算法),然后使用以下项创建绑定:
ResourceBundle b;
b = new PropertyResourceBundle(properties.openStream());
另外,代码可按如下所示使用基本 Java 支持来定位清单的正确 NL 变体:
ResourceBundle b;
ClassLoader l;
l = new URLClassLoader(new URL[] {<targetDirectoryURL>}, null);
b = ResourceBundle.getBundle("install",Locale.getDefault(),l);
所生成的资源绑定可在 IPluginDescriptor.getResourceString(String,ResourceBundle) 中使用以实际返回清单属性正确的已转换字符串。
将 NL 文件封装为插件段会导致稍为复杂一些的安装结构。主要益处是在操作之后可将 NL 内容添加到基元中(即不必同时传送)。它还允许段独立于基本插件之外而发展(对于服务更新)。
以下是所产生的用于封装 NL 的备用安装结构。
封装与插件“内联”的 NL
install/
plugins/
<pluginId>_<version>/
(“插件”文件)
nl/
<locale>/
(NL 文件)
例如:
install/
plugins/
my.funky.plugin_1.0.1/
plugin.xml
my.jar ... 包含类和缺省资源
nl/
de_DE/
my.jar ... 包含已转换的变化
将 NL 封装为插件段
install/
fragments/
<fragmentId>_<version>/
fragment.xml
nl/
<locale>/
(NL 文件)
例如:
install/
fragments/
my.funky.plugin_german_1.0.1/
fragment.xml
nl/
de_DE/
my.jar ... 包含已转换的变化
语言环境目录名遵循标准 Java 语言环境命名约定。
注意,通常情况下,基本插件内容应总是包括缺省 NL 资源,以便功能在没有适当的语言环境树的情况下以合法的方式运作(即,最好是在用户界面中显示缺省字符串而不是资源标识)。
在 Eclipse 平台文档中别的地方描述了用于管理 NL 目录和段的运行时机制、fragment.xml 格式和 API。
将特定于目标的文件封装为插件段会导致稍为复杂一些的安装结构。主要的益处是在操作之后可将指定目标支持添加到基元中(即不必同时传送)。它还允许段独立于基本插件之外而发展(对于服务更新)。
以下是所产生的用于封装特定于目标的文件的备用安装结构。
封装与插件内联的特定于目标的支持
install/
plugins/
<pluginId>_<version>/
(“插件”文件)
os/
<os-name>/
(特定于操作系统的文件)
ws/
<windowing-system-name>/
(特定于窗口系统的文件)
例如:
install/
plugins/
my.funky.plugin_1.0.1/
plugin.xml
my.jar
os/
solaris/
libfoo.so
ws/
motif/
my.jar
将特定于目标的支持封装为插件段
install/
fragments/
<fragmentId>_<version>/
fragment.xml
os/
<os-name>/
(特定于操作系统的文件)
ws/
<windowing-system-name>/
(特定于窗口系统的文件)
例如:
install/
fragments/
my.funky.plugin_solaris_1.0.1/
fragment.xml
os/
solaris/
libfoo.so
ws/
motif/
my.jar
用于目录名的目标标识符由 Eclipse 定义(参见 org.eclipse.core.boot.BootLoader 的 Javadoc)。
在 Eclipse 平台文档中别的地方描述了用于管理特定于目标的目录和段的运行时机制、fragment.xml 格式和 API。
完全 Eclipse 安装包含下列文件结构:
<installation root>/
install/
install.properties
components/
<componentId>_<version>/
install.xml
install_<locale>.properties (可选)
configurations/
<configurationId>_<version>/
install.xml
install_<locale>.properties (可选)
(其他“产品”文件)(可选)
plugins/
<pluginId>_<version>/
plugin.xml
(其他插件文件)
fragments/
<fragmentId>_<fragmentVersion>/
fragment.xml
(其他段文件,可能还包括 plugin.xml)
以前就为组件 jar 和配置 jar 指定了目录和文件的定义。
install.properties 文件包含可配置启动特性。它反映平台和所安装应用程序的当前启动设置。它的详细用法在“启动 Eclipse”一节中描述。此文件最初是作为新安装的一部分安装的。仅当以后每次更新 Eclipse 安装时,才由更新管理器更新它。如果用另外某种与原来安装不兼容的方法更新文件,则将恢复上一有效状态。
文件的格式为 Java 特性文件格式,且包含以下内容:
application=<applicationId>
application.configuration=<configurationId>_<version>
runtime=<pluginId>_<version>
例如
application=
application.configuration=com.ibm.wsa_1.0.3
runtime=org.eclipse.core.boot_1.1.4
特性定义如下所示:
注意:如本节中所指定的那样,基于 Eclipse 的产品的初始安装还必须安装反映正确初始启动设置的 install.properties 文件。若未这样做,则会导致无法启动该产品。
<installation root>/
install/
components/
install.index(可选)
<componentId>_<version>/
install.xml
install_<locale>.properties(可选)
<componentId>_<version>.jar
configurations/
install.index(可选)
<configurationId>_<version>/
install.xml
install_<locale>.properties(可选)
<configurationId>_<version>.jar
可通过从组件 jar 或配置 jar 部分地解压缩安装清单(和任何安装资源绑定),然后将整个 jar 复制到结果目录结构(与 install.xml 同级)中,就可创建参考安装。公开 install.xml 将允许更新管理器确定在给定站点中哪些内容可用。一旦进行了选择, 就会下载和安装相应的 .jar。
当由除直接文件 i/o 之外的协议访问参考安装站点时,该站点还必须包含可选的 install.index(在 components/ 和 configurations/ 目录中)。此文件是一个简单的目录“目录”。它包含处于单独行上的实际子目录名。
例如:
<installation root>/
install/
components/
install.index
org.eclipse.platform_1.0.1/
org.eclipse.jdt_2.9.5/
org.eclipse.pde_1.0.4/
install.index 文件将包含
org.eclipse.platform_1.0.1
org.eclipse.jdt_2.9.5
org.eclipse.pde_1.0.4
当通过直接文件 i/o(如“文件”URL)引用“站点”时,不需要 install.index 文件。然而,注意,如果该文件存在,则甚至会在直接文件 i/o 访问的情况下使用它。通过这种方法,可由站点管理使用该文件来控制实际公开哪些配置和组件。通常,当不想将包含在配置中的组件作为独立项(即,仅通过某些配置进行管理)下载和安装时,这是很有用的。在这种情况下,将直接公开配置,但不公开组件。将仅通过公开的配置定位组件。
更新管理器从不更新现有的插件目录结构。它只安装先前不存在的插件版本。如果插件目录已存在(例如:包括在另外某个(版本的)组件中),就不会再次安装它。更新管理器不验证现有目录内容是否与组件 jar 中的目录内容相匹配。因此,必须在插件目录名中正确反映插件版本标识符。
例如,组件 jar 可能包含
install/
components/
com.xyx.etools_1.3.5/
install.xml
splash.bmp
readme.txt
license.txt
notes/
jspedit.txt
debug.txt
每次更新管理器更新和保存此信息(保存在平台关闭时完成)时,就克隆此状态信息,且先前的状态就保存为按时间顺序排列的更新序列。更新管理器维护若干个状态生成(先前状态的数目是可设置的)。会定期收集(删除)旧状态版本及相应的配置和组件作为更新管理器清理处理的一部分。
状态的后备级副本提供了用于从错误更新中恢复的机制。在此方案中,“错误”表示更新管理器成功下载及应用了更改,但该更改导致发生问题。
安装程序需要执行下列操作:
为了补充更新管理器所做的更改,“传统”卸载程序可强制除去下列 Eclipse 安装目录内的所有文件:
安装程序需要执行下列操作:
当使用不允许对卸载过程进行以上控制(即:禁止除去所安装的文件)的安装程序技术时,应小心进行。Linux 上的 RPM 就是这样一个示例。在这些情况下,应避免对合并安装使用特定安装程序技术,或者决不应执行结果卸载。
“传统”卸载程序可通过使用合并的安装“根目录”文件来支持安全除去所安装的功能。这些文件是作为合并安装的一部分安装(可选)的,并充当相应配置和组件的锚点。Eclipse 平台在启动期间检测除去“根目录”文件的情况,并安全除去列示的配置和组件。
注意:与配置和组件文件本身不同,“根目录”文件不遵从更新管理器进行的更改。因此,“传统”卸载程序可因这些情况而在安装之后保留下来。
安装之后,将“根目录”文件置于 Eclipse 安装树内的 install/info/ 目录中(与 install/configurations 和 install/components 目录同级)。文件使用下列命名约定:
<merged-installation-identifier>.install
Eclipse 平台不指定标识符的格式(不作任何形式的解释)。要使发生命名冲突的可能性降至最小, 强烈建议标识符使用基于供应商因特网域名(例如 com.xyz.toolpack.install)的命名约定。
“根目录”文件的内容使用 Java 特性文件格式,并包含以下内容:
configurations=[<configId>_<version> [, <configId>_<version>]*
]
components=[<compId>_<version> [,<compId>_<version>]*
]
其中
[]为可选元素
* 为重复的分组
(在纯英文中,所有特性都是以逗号分隔的(相应的以版本为后缀的标识符的)列表)
建议基于 Eclipse 的产品使用操作系统注册机制以跟踪所有安装的 Eclipse 平台的位置。这允许在决定是创建新平台安装还是将组件合并到现有安装中时进行简单查找。在未提供这种注册机制的平台上,将提示用户显式标识 Eclipse 安装目录。
安装程序通常会创建新安装或将组件合并到现有安装中。创建新安装还应更新注册结构。
在 Windows 上,Windows 注册表就用于此目的。以下是建议的用于标识 Eclipse 平台安装目录的注册表键结构:
eclipse.org/
platforms/
<product name>
<product name> 键标识供应商和/或创建了新 Eclipse 平台安装的主导应用程序。整个键映射至下列属性
label = <product name> 键的可显示标号。创建时进行本地化。
directory = <absolute path>
特定于操作系统的本机组件(如 ActiveX)需要不由 Eclipse 更新管理器处理的定制安装。定制安装程序向适当的操作系统服务注册组件并更新任何标准搜索路径。Eclipse 平台不提供任何对必需本机组件的自动检查。需要插件代码来实现必需的检查/恢复逻辑。有可能将“标记”插件创建为定制安装程序的一部分以指示某些本机组件的存在并允许其他插件指定从属项。然而,此方法并非十分安全,不能用作满意的本机从属项的绝对保证。
Eclipse 平台还允许并行配置和执行同一插件的多个版本。这特别适合包含共享运行时库的插件。共享运行时的给定用户可能想要指定特定插件版本的从属项。这样的插件必须仅声明其运行时库(在 plugin.xml 的 <runtime> 部分中),且一定不能声明平台的任何其他添加项(尤其一定不能声明扩展点和/或添加扩展)。
为了支持这一点,Eclipse 平台定义用于标识插件的方案、用于命名文件系统内插件目录的约定和一组用于在平台启动期间配置和执行定位的插件的规则。
插件是由类似于 Java 包名的结构化字符串与多位版本标识符的组合标识的。版本标识符由指示不兼容生成的主要组件和指示插件的兼容进展的次要组件组成。
插件 | 版本 | 建议的目录名 |
org.eclipse.ui | 1.3.17 | org.eclipse.ui_1.3.17 |
edu.xyz.tools | 1.0.1 | edu.xyz.tools_1.0.1 |
平台提供了用于处理版本标识符的 API。
平台提供了可由插件用来处理每一个迁移情况的基本设施,然而,正确使用这些设施毕竟是插件开发者的职责。
如插件执行那样,它们可将插件特定信息写入到若干个工作位置中。对工作位置的引用是使用下列 API 调用获得的:
向后迁移要求进行一些属于插件开发者工作范围的附加工作。实质上,插件的版本 n+1 需要以这样一种方法写数据:版本 n 至少可检测到此情况。有若干种可能的插件可用来处理此方案的技术。