Eclipse 3.0 与 3.1 之间的不兼容性

Eclipse 在 3.0 与 3.1 之间进行的某些更改在方式上是不兼容的,它们会影响插件。下列各项描述了所更改的方面,并且提供了有关从 3.0 插件迁移到 3.1 的指示信息。注意,如果您在 3.1 上运行 3.0 插件时遇到了问题,只需参阅本文档。

  1. 插件首选项
  2. 对 IPath 约束的更改
  3. 扩展注册表
  4. 代码格式化程序选项
  5. API 合同对 AntCorePreferences 的更改
  6. API 合同对 JFace 中的 Policy 类的更改
  7. API 合同更改为允许使用空的缺省透视图
  8. API 合同对 IViewLayout 的更改
  9. API 合同对 IVMInstall 的更改
  10. SelectionEnabler.SelectionClass 已成为包可视的
  11. ContributionItem.getParent() 可以返回空值
  12. 对 IPropertySource 和 IPropertySource2 中的 isPropertySet(boolean) 的更改
  13. 从 org.eclipse.ui.commands 扩展点中删除了 handlerSubmission 元素
  14. TeamUI 中的静态非最终 API 字段 GLOBAL_IGNORES_CHANGED 已变为最终字段
  15. 使用 FillLayout 的 ClassCastException
  16. 使用已被除去的父代来创建窗口小部件

1. 插件首选项

受影响的内容:通过覆盖 Plugin#initializeDefaultPreferences 来初始化缺省插件首选项值的插件或者使用首选项更改侦听器的插件。

描述:在 Eclipse 3.1 中,从 org.eclipse.ui.plugin.AbstractUIPlugin#getPreferenceStore 中获得的 org.eclipse.jface.preference.IPreferenceStore 对象已被迁移到由 org.eclipse.core.runtime 插件提供的新 3.0 Eclipse 首选项框架的顶部。

需要执行的操作:因此,使用首选项 API 的客户机应检查两个可能的问题:

  1. 在首选项更改事件中包含的对象类型是没有保证的;事件中的旧值和新值都可以为空、字符串或输入的对象。因此,要成为一个好的客户机,首选项更改侦听器应能够处理所有这三种可能的情况。
  2. 如果您的插件使用 org.eclipse.ui.plugin.AbstractUIPlugin#initializeDefaultPreferences,则您必须确保在必需插件的插件列表中包括了 org.eclipse.core.runtime.compatibility 插件(因为已从 org.eclipse.ui.workbench 插件中除去了此依赖项)。

有关更多详细信息,请参阅首选项库文档。

2. 对 IPath 约束的更改

受影响的内容:创建、处理或存储 IPath 对象的插件。

描述:在 Eclipse 3.0 中,IPath 对路径的段有一些限制,这些限制比底层操作系统的限制更严格。它们包括:

当平台的数据位置(工作空间)位于没有这些限制的文件系统上时,在 Eclipse 3.1 中已取消这些限制。

需要执行的操作:为了能够正确处理路径的扩展范围,应查看插件内 PathIPath 的所有用法并按以下所述进行更新。大多数未修改的并且在 3.0 中被认为是合法路径的插件,它们的行为将与 3.0 中完全一样。然而,除非执行了这些规定的更改,否则,如果涉及到在 3.1 中被认为是合法而在 3.0 中被认为是非法的路径,则这些插件可能会失败。

某些插件以一种在不同平台之间都可读的格式来存储路径的字符串表示,应将这种插件迁移至新的 Path.fromPortableString 工厂方法。此方法以一种与平台无关的格式生成 IPath 实例。可以使用 IPath.toPortableString 方法来创建此路径的字符串表示。受影响的元数据文件的示例包括存储在 Eclipse 工作空间项目(.project 和 .classpath 等)内的文件和存储在首选项库(org.eclipse.core.runtime.preferences.IPreferencesService)中的所有路径。

注意:fromPortableString 将正确读取使用 Eclipse 3.0 IPath.toString 方法创建的所有路径字符串,但不能正确读取使用 Eclipse 3.1 toString 方法创建的路径字符串。因此,在大多数情况下,不需要对现有元数据文件格式进行更改,只是需要以 toPortableString 开始写入路径和以 fromPortableString 开始读取路径。

从硬编码字符串文件创建路径且假定“:”和“\”在所有平台上都有特殊意义的插件将需要迁移。最容易的解决方案是将字符串路径文字限制为在所有平台上都受支持的子集(避免使用冒号和反斜杠字符)。通过使用由 Path.toPortableString 生成的可移植路径字符串格式,路径文字可以支持一组完整的有效 Unix 路径。此格式将第一个单冒号(“:”)解释为设备分隔符,将斜杠(“/”)解释为段分隔符,并将双冒号(“::”)解释为文字冒号字符。例如,在 Unix 平台上,代码 new Path("c:/temp") 现在将创建一个具有两个段的相对路径。同样地,new Path("a\\b") 现在将在 Unix 平台上创建一个具有单个段的路径,而在 Windows 上将创建一个具有两个段的路径。

使用 IPath.append(String) 方法构造路径且假定“:”和“\”在所有平台上都有特殊意义的插件可能需要更新其代码。在 Eclipse 3.1 中,此方法使用特定于操作系统的设备和段定界符来解释提供的路径字符串。例如,在 Unix 平台上调用 append("a\\b") 现在将附加单个段,而在 Windows 上,它将继续附加两个段。

在所有平台上,平台读取和解释的任何数据文件都不再把“:”和“\”视为特殊字符。可以在多个平台上读取的数据文件中存储的所有路径都必须具有可移植格式。例如,plugin.xml 中的图标文件路径和其它路径只能使用“/”作为路径段分隔符。

3. 扩展注册表

受影响的内容:处理或保留 Eclipse 平台的插件或扩展注册表中 IExtensionPointIExtensionIConfigurationElement 对象的插件。

描述:在 3.0 之前,从扩展注册表(以前的插件注册表)获取的所有对象永远是好的。在 Eclipse 3.0 中进行了一些更改,以允许动态地添加或除去插件而不必重新启动 Eclipse。当除去某个插件而不重新启动时,该插件在扩展注册表中的条目必定会变为无效条目。这意味着:如果有另外一个插件一直占用先前从已删除的插件扩展注册表条目中获取的对象,则此插件所占用的对象将是一个无效对象。客户机接收到的唯一的暗示可能来自于对 IRegistryChangeEvent 的侦听。自 Eclipse 3.0 以来,该问题就已存在,但实际上很少遇到,因为除去插件而不重新启动 Eclipse 是非常少见的。

在 3.1 中已通过以下方式解决此问题:

需要执行的操作:如果插件需要成为可动态察觉的(即,能够处理插件的动态添加或删除),则处理来源于其它某些插件的 IExtensionPointIExtensionIConfigurationElement 对象的代码必须加以更改才能捕获 IRegistryChangeEvent,就完全像它是已检查的异常一样。捕获异常(而不是 isValid() 预检查)是在插件被并发线程除去的情况下进行处理的唯一可靠方法。

4. 代码格式化程序选项

受影响的内容:以编程方式访问 Java 代码格式化程序选项的插件。

描述:在 Eclipse 3.0 中,代码格式化程序选项 org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_TAB_CHAR 的值只能是 TABSPACE。该规范没有明确地提及的是,值类型是在以后的发行版中可能增大的枚举。在 Eclipse 3.1 中,添加了第三个可能值 MIXED 以解决 73104 错误。该规范已更改,以包括这一新值并允许以后添加更多的值。

需要执行的操作:以编程方式读取或设置此代码格式化程序选项的客户机应检查其代码以考虑新的第三个值并确保以健壮方式编写它,以便在它遇到意外的选项值时平稳地退出。

5. API 合同对 AntCorePreferences 的更改

受影响的内容:成为 org.eclipse.ant.core.AntCorePreferences 的子类或实例化它的插件

描述:在 Eclipse 3.0 中,未对类 org.eclipse.ant.core.AntCorePreferences 进行标记以便客户机不能实例化它或成为它的子类。这是一个疏忽,在 Eclipse 3.1 中已解决该问题,已将该类标记为不接受子类或被实例化。

需要执行的操作:以编程方式创建 org.eclipse.ant.core.AntCorePreferences 的实例的客户机应迁移其代码以使用 org.eclipse.ant.core.AntCorePlugin.getPreferences() 来检索首选项。任何子类都将需要进行改写,以便不再成为 org.eclipse.ant.core.AntCorePreferences 的子类。

6. API 合同对 JFace 中的 Policy 类的更改

受影响的内容:覆盖由工作台设置的 JFace 日志的 RCP 应用程序。

描述:在 Eclipse 3.0 中,工作台通过将工作台插件的日志直接传递至 org.eclipse.jface.util.Policy.setLog(ILog) 来将工作台的日志设置为用于记录 JFace 错误的日志。在 3.1 中,ILog 的依赖项已从 JFace 中除去,以便使用 Eclipse 运行时外部的 SWT 和 JFace 来启用独立的应用程序。并且已引进了一个新的接口 ILogger 来满足 JFace 的需要。工作台已更改,以提供回绕工作台 ILogILogger。有关进一步的详细信息,请参阅错误 88608

需要执行的操作:大多数 RCP 应用程序应该不需要覆盖由工作台设置的日志,但如果它们先前调用了 Policy.setLog(ILog),则需要更改它们以改为传递 ILogger

7. API 合同更改为允许使用空的缺省透视图

受影响的内容:期望非空缺省透视图的 RCP 应用程序。

描述:为了允许 RCP 应用程序使用未打开任何透视图的空窗口启动(增强 71150),WorkbenchAdvisor.getInitialWindowPerspectiveId()IPerspectiveRegistry.getDefaultPerspective() 已更改为允许返回空值。在 IDE 中,总是有一个缺省透视图,因此 IPerspectiveRegistry.getDefaultPerspective() 将不会返回空值。同样,如果现有 RCP 应用程序先前从 WorkbenchAdvisor.getInitialWindowPerspectiveId() 返回了非空值,则 IPerspectiveRegistry.getDefaultPerspective() 仍将返回非空值。

需要执行的操作:客户机应该不需要执行任何操作。

8. API 合同对 IViewLayout 的更改

受影响的内容:实现 org.eclipse.ui.IViewLayout 的插件。

描述:在 Eclipse 3.0 中,未对类 org.eclipse.ui.IViewLayout 进行标记以便客户机不能实现它。这是一个疏忽,在 Eclipse 3.1 中已解决该问题,已将该类标记为客户机不能实现它。

需要执行的操作:任何实现类都将需要进行改写,以便不再实现 org.eclipse.ui.IViewLayout

9. API 合同对 IVMInstall 的更改

受影响的内容:实现 org.eclipse.jdt.launching.IVMInstall 的插件。

描述:在 Eclipse 3.0 中,未对类 org.eclipse.jdt.launching.IVMInstall 进行标记以便客户机不能直接实现它。这是一个疏忽,在 Eclipse 3.1 中已解决该问题,已将该类标记为客户机不能直接实现它。为了保持二进制兼容性,我们仍允许客户机直接实现此接口,但强烈建议客户机作为 org.eclipse.jdt.launching.AbstractVMInstall 的子类。实现 IVMInstall 的客户机还应该实现新的可选接口 org.eclipse.jdt.launching.IVMInstall2AbstractVMInstall 现在实现了该接口。建议客户机实现新接口 IVMInstall2 以避免错误 73493 中记录的问题。建议的迁移方法是作为 AbstractVMInstall 的子类。

需要执行的操作:尚未成为 org.eclipse.jdt.launching.AbstractVMInstall 的子类的任何实现类都应该改写,以便成为 org.eclipse.jdt.launching.AbstractVMInstall 的子类。

10. SelectionEnabler.SelectionClass 已成为包可视的

受影响的内容:使用 org.eclipse.ui.SelectionEnabler.SelectionClass 的插件。

描述:在 Eclipse 3.0 中,嵌套的实现类 org.eclipse.ui.SelectionEnabler.SelectionClass 是公用的,对它的使用没有任何限制。这是一个疏忽,在 Eclipse 3.1 中已解决该问题,已经使该类成为包可视的。

需要执行的操作:实例化或扩展 org.eclipse.ui.SelectionEnabler.SelectionClass 的任何类都将需要返工以便不再引用此类。

11. ContributionItem.getParent() 可以返回空值

受影响的内容:org.eclipse.jface.action.ContributionItem 的子类上调用 getParent() 的插件。

描述:在 Eclipse 3.0 中,方法 org.eclipse.jface.action.ContributionItem.getParent() 未指定它可以返回空值。这是一个疏忽,在 Eclipse 3.1 中已通过 该方法的 Javadoc 来阐明它何时可以返回空值而加以解决。有关更多详细信息,请参阅错误 92777

需要执行的操作:调用 ContributionItem.getParent() 的任何代码必须确保它可以处理空结果。

12. 对 IPropertySource 和 IPropertySource2 中的 isPropertySet(boolean) 的更改

受影响的内容:实现 org.eclipse.ui.views.properties.IPropertySourceIPropertySource2 的插件。

描述:在 Eclipse 3.0 中,方法 org.eclipse.ui.views.properties.IPropertySource.isPropertySet(boolean) 的规范被错误地更改为:如果指定的属性不具有有意义的缺省值,则指定应返回 true。在先前版本中,指定了在这种情况下应返回 false。这是一个不小心的对 API 的破坏性更改,尽管该实现仍像以前一样工作(如果属性源实现了 IPropertySource 而不是 IPropertySource2)。在 3.1 中已改正此错误,方法是将 IPropertySource.isPropertySet(boolean) 还原为它的先前规范(在这种情况下应该返回 false),而 IPropertySource2.isPropertySet(boolean) 在这种情况下则应该返回 true。 有关更多详细信息,请参阅错误 21756

需要执行的操作:在某些属性不具有有意义的缺省值时,应该检查实现 IPropertySource 或 IPropertySource2 的任何类以确保它们返回 isPropertySource(boolean) 的适当值。客户机应检查“属性”视图中的“恢复缺省值”按钮是否按它们的属性源所预期的那样工作。

13. 从 org.eclipse.ui.commands 扩展点中删除了 handlerSubmission 元素

受影响的内容:使用了 Eclipse 3.0 中对 org.eclipse.ui.commands 扩展点引入了实验性 handlerSubmission 元素的插件。

描述:在 Eclipse 3.0 中,对 org.eclipse.ui.commands 扩展点引入了一个实验性元素。此元素旨在成为通过 XML 注册处理程序的方法。从那时开始,就引入了一种更高级的机制,即 org.eclipse.ui.handlers 扩展点。由于该元素被标记为实验性的,所以现在已除去了该元素。

需要执行的操作:任何定义了 handlerSubmission 元素的插件都应该迁移到 org.eclipse.ui.commands 扩展点。

14. TeamUI 中的静态非最终 API 字段 GLOBAL_IGNORES_CHANGED 已变为最终字段

受影响的内容:设置 TeamUI 的 GLOBAL_IGNORES_CHANGED 字段的插件。

描述:在 Eclipse 3.0 中,已在 TeamUI 类中添加了 GLOBAL_IGNORES_CHANGED 字段。此字段是一个常量,在属性更改事件中,使用此字段来指示 Team 插件维护的全局忽略列表已更改。在 3.0 中,未将此字段标记为最终字段,但应该这样标记。在 3.1 中,已将此字段标记为最终字段。

需要执行的操作:任何设置以上字段的插件都不再能够这样做。

15. 使用 FillLayout 的 ClassCastException

受影响的内容:不正确地使用 FillLayout 的插件。

描述:在 Eclipse 3.0 中,没有任何布局数据与 FillLayout 相关联,如果应用程序将布局数据赋予 FillLayout 管理的子代,它将被忽略。在 Eclipse 3.1 中,添加了对 FillLayout 的支持,允许对大小信息进行高速缓存以提高调整大小时的性能。高速缓存的数据存储在与 FillLayout 管理的每个子代相关联的 FillData 对象中。如果应用程序不正确地将布局数据赋予子代,在对父代调用 computeSize 时就会抛出 ClassCastException。

需要执行的操作:查找 FillLayout 中任何被赋予布局数据的子代并停止赋予该布局数据。

16. 使用已被除去的父代来创建窗口小部件时将抛出 IllegalArgumentException

受影响的内容:创建窗口小部件时捕获异常的插件。

描述:在 Eclipse 3.0 中,如果使用已被除去的父代来创建窗口小部件,不会抛出异常,窗口小部件代码将在以后某个时刻失败,或者将抛出带有文本“窗口小部件已被破坏”的 SWTException。在 Eclipse 3.1 中,如果使用已被除去的父代来创建窗口小部件,构造函数将抛出带有文本“自变量无效”的 IllegalArgumentException。

需要执行的操作:任何处理创建窗口小部件时发生的 SWTException 的代码都还需要处理 IllegalArgumentException。