Eclipse 2.1 版和 3.0 版的不相容性

Eclipse 2.1 版和 3.0 版的不相容性,在於它們對於外掛程式的影響。 下列項目主要在說明變更的區域,並且提示您如何把 2.1 版的外掛程式移轉到 3.0。 請注意,如果您無法在 3.0 版執行 2.1 版的外掛程式,只需要看看這裡就行。

  1. 外掛程式 Manifest 版本
  2. 重組平台 UI 外掛程式
  3. 重組平台核心執行時期外掛程式
  4. 移除 Xerces 外掛程式
  5. Eclipse 3.0 的並行功能更強
  6. 針對 IFiles 開啟編輯器
  7. 編輯器 goto 標記
  8. 編輯器啟動程式
  9. 編輯器登錄
  10. 工作台標記說明登錄
  11. 文字編輯器文件提供者
  12. 文字編輯器
  13. 無監視器型的註釋支援
  14. 主控台視圖
  15. Java 岔斷點接聽器
  16. UI 執行緒的剪貼簿存取
  17. 按鍵懸置事件
  18. 利用 Tab 鍵遍訪的自訂控制項
  19. SWT 表格和樹狀結構小組件中的選取事件順序
  20. 狀態物件中的新嚴重性層次
  21. 與建置相關聯的資源變更通知
  22. 在進行工作區作業期間的中間通知
  23. URL 串流處理常式延伸
  24. 類別載入順序
  25. 沒有設定類別載入器保護網域
  26. PluginModel 物件強制轉型
  27. ILibrary 實作不完整
  28. URL 格式的假設無效
  29. BootLoader 方法已被移走/刪除
  30. 外掛程式匯出不會自動併入外掛程式的 JAR
  31. 重新匯出執行時期 API
  32. 在平台上剖析方法的外掛程式
  33. 由片段提供的外掛程式庫
  34. 對建置 Script 所做的變更
  35. 對 PDE 建置 Ant 作業所做的變更
  36. 對 eclipse.build Ant 作業所做的變更
  37. 對 eclipse.fetch Ant 作業所做的變更
  38. 置換 install.ini

1. 外掛程式 Manifest 版本

外掛程式(以及外掛程式片段)的 Manifest 檔標頭,現在多加了一行,可以識別適當的外掛程式 Manifest 版本。 在 3.0 版之前,外掛程式並沒有這些 <?eclipse ...?> 字行,而 3.0 版之後,一律都有了。 這項改變是為了讓 Eclipse 執行時期 能夠可靠的辨識 3.0 版之前、尚未移轉到 3.0 版的外掛程式, 讓它得以為這類外掛程式,自動提供更強大的二進位相容性。 下面是 plugin.xml 檔的一般格式(fragment.xml 與它類似):

<?xml version="1.0" encoding="big5"?>
<?eclipse version="3.0"?>
<plugin ...>
    ...
</plugin>

PDE 3.0 所建立的外掛程式 Manifest,會自動具備這個格式。 我們強烈建議您採用 PDE 外掛程式移轉工具。 它會把指定的那一行,自動插到 2.1 版外掛程式和外掛程式片段的 Manifest 中, 並且提出許多其他這裡所說明的變更。

如果您要在 plugin.xml 加入這個指引(以手動方式或者利用 PDE 都可以),則也必須更新該檔,讓它明確列出它所仰賴的外掛程式。 舉例來說,在 Eclipse 3.0 版之前,org.eclipse.core.runtime 和 org.eclipse.core.boot 是必備的項目。 但到了 3.0 版,就不再需要 org.eclipse.core.boot 了, 開發人員必須根據情況,選擇 org.eclipse.core.runtime 或 org.eclipse.core.runtime.compatibility(或者兩者都不選)。

附註:這是其中一項不相容的地方,但這一點並影響 Eclipse 3.0 版執行 2.1 版二進位外掛程式的方式。

2. 重組平台 UI 外掛程式

org.eclipse.ui 外掛程式曾經是主要的平台 UI 外掛程式, 現在卻只能為通用(亦即,非 IDE 專屬的)工作台提供 API 和延伸點。 選擇性和 IDE 專屬的 API 與延伸點,都已經移到其他外掛程式了。

這項改變產生了雙重的影響:(1) 被移走的 org.eclipse.ui 延伸點有了新的延伸點 ID;(2) 必要外掛程式的清單也跟著改了。

下表所示的 org.eclipse.ui 延伸點,已經移到不同的外掛程式,因此延伸點 ID 也跟著改變。 如果現有的外掛程式提供延伸給被移走的延伸點, 則外掛程式 Manifest 檔中 <extension> 元素的 "point" 屬性中的參照, 也必須跟著改變,才能配合對應的新延伸點 ID。 而這項修改作業是由 PDE 外掛程式移轉工具負責。

附註:這是其中一項不相容的地方,但這一點並影響 Eclipse 3.0 版執行 2.1 版二進位外掛程式的方式。 Eclipse 3.0 版執行時期會自動偵測 3.0 版以前的外掛程式 (如果外掛程式 Manifest 中少了前面提及的 <?eclipse version="3.0"?> 這一行), 並且自動補償這些延伸點和外掛程式相依關係的改變。

舊的延伸點 ID

新的延伸點 ID

org.eclipse.ui.markerHelp org.eclipse.ui.ide.markerHelp
org.eclipse.ui.markerImageProviders org.eclipse.ui.ide.markerImageProviders
org.eclipse.ui.markerResolution org.eclipse.ui.ide.markerResolution
org.eclipse.ui.projectNatureImages org.eclipse.ui.ide.projectNatureImages
org.eclipse.ui.resourceFilters org.eclipse.ui.ide.resourceFilters
org.eclipse.ui.markerUpdaters org.eclipse.ui.editors.markerUpdaters
org.eclipse.ui.documentProviders org.eclipse.ui.editors.documentProviders
org.eclipse.ui.workbench.texteditor.
markerAnnotationSpecification
org.eclipse.ui.editors.markerAnnotationSpecification

下表將列出先前由 org.eclipse.ui 外掛程式提供、已經移到其他外掛程式的 API 套件。 (API 套件、類別、欄位和方法的名稱則不變)。 在某些情況下,如果橫跨多個外掛程式,API 套件也會跟著分割。 由於所有外掛程式看得到的 API 類別,是由必要外掛程式的外掛程式清單所決定, 因此這些改變,可能需要調整現有外掛程式 Manifest 中的 "<requires>" 元素, 以收回 API 類別的存取權。

這項改變只會影響仰賴 org.eclipse.ui 外掛程式的外掛程式 (亦即,把 <import plugin="org.eclipse.ui"/> 加到 外掛程式 Manifest 的 <requires> 區段中);其他外掛程式則不受影響。 如果受到影響,也許需要變更 <import> 元素,或者新增其他的 <import> 元素, 讓所有您外掛程式需要的 API 類別,都列入範圍中。 我們強烈建議您,外掛程式只要敘述它們真正使用之外掛程式的相依關係即可。 加入不必要的相依關係,只會降低執行時期效能,因為 Java 類別載入器必須在所有的相依關係中搜尋類別。 (PDE 外掛程式移轉工具會修正相依關係,並且幫助您決定一個最小的相依關係集)。

API 套件

2.1 版外掛程式

對應的 3.0 版外掛程式

org.eclipse.jface.text.* org.eclipse.ui org.eclipse.jface.text
org.eclipse.text.* org.eclipse.ui org.eclipse.jface.text
org.eclipse.ui org.eclipse.ui org.eclipse.ui, org.eclipse.ui.ide
org.eclipse.ui.actions org.eclipse.ui org.eclipse.ui, org.eclipse.ui.ide
org.eclipse.ui.dialogs org.eclipse.ui org.eclipse.ui, org.eclipse.ui.ide
org.eclipse.ui.editors.* org.eclipse.ui org.eclipse.ui.editor
org.eclipse.ui.model org.eclipse.ui org.eclipse.ui, org.eclipse.ui.ide
org.eclipse.ui.part org.eclipse.ui org.eclipse.ui, org.eclipse.ui.ide
org.eclipse.ui.texteditor org.eclipse.ui org.eclipse.ui.workbench.texteditor, org.eclipse.ui.editors
org.eclipse.ui.texteditor.* org.eclipse.ui org.eclipse.ui.workbench.texteditor
org.eclipse.ui.views.bookmarkexplorer org.eclipse.ui org.eclipse.ui.ide
org.eclipse.ui.views.contentoutline org.eclipse.ui org.eclipse.ui.views
org.eclipse.ui.views.markers org.eclipse.ui org.eclipse.ui.ide
org.eclipse.ui.views.navigator org.eclipse.ui org.eclipse.ui.ide
org.eclipse.ui.views.properties org.eclipse.ui org.eclipse.ui.views
org.eclipse.ui.views.tasklist org.eclipse.ui org.eclipse.ui.ide
org.eclipse.ui.wizards.datatransfer org.eclipse.ui org.eclipse.ui.ide
org.eclipse.ui.wizards.newresource org.eclipse.ui org.eclipse.ui.ide

3. 重組平台核心執行時期外掛程式

Eclipse 3.0 版平台執行時期,是以 OSGi 為基礎, 因此必須變更 org.eclipse.core.runtime 和 org.eclipse.core.boot 這兩個平台執行時期外掛程式的結構。

新的 org.eclipse.core.runtime.compatibility 外掛程式,可以在舊版和新版 API 之間提供實作橋接, 它同時是之前位於 org.eclipse.core.runtime 和 org.eclipse.core.boot 中、目前已經作廢的許多 API 的新家。 平台執行時期延伸點並不受重組的影響。

在將現有的外掛程式移轉到 3.0 版時,也必須更新外掛程式的 Manifest, 以反映 Eclipse 平台執行時期外掛程式的新結構。 必要時,PDE 外掛程式 Manifest 移轉工具,會在 org.eclipse.core.runtime.compatibility 加入一個相依關係。

同時也請注意,如果您把外掛程式標為 3.0 版(使用 <?eclipse version="3.0"?>), 而且外掛程式也定義了一個 Plugin 類別,則您必須在外掛程式 Manifest 中明確設定 <import plugin="org.eclipse.core.runtime.compatibility"/>, 否則就是讓 Plugin 類別定義預設建構子。

附註:這是其中一項不相容的地方,但這一點並影響 Eclipse 3.0 版執行 2.1 版二進位外掛程式的方式。 Eclipse 3.0 版執行時期會自動偵測 3.0 版以前的外掛程式 (如果外掛程式 Manifest 中少了 <?eclipse version="3.0"?> 這一行), 並且自動補償您對平台執行時期所做的這些改變。

4. 移除 Xerces 外掛程式

由於 org.eclipse.xerces 外掛程式再也用不著,因此目前已經將它刪除了。XML 剖析支援是內建在 J2SE 1.4 版中,而 Xerces 外掛程式的存在,也會構成類別載入器的衝突。 之前 org.eclipse.xerces 外掛程式所提供的 javax.xml.parsers、org.w3c.dom.* 和 org.xml.sax.* API 套件, 現在都可以在 J2SE 程式庫取得。

如果您的外掛程式需要 org.eclipse.xerces 外掛程式,則必須變更您的外掛程式 Manifest,移除這個相依關係。 做完這個動作之後,外掛程式的程式碼就可以直接編譯和執行,不必另做更改。

具有 org.eclipse.xerces 外掛程式相依關係的 2.1 版二進位外掛程式, 在標準 Eclipse 3.0 版配置執行時,會遺漏一個必備項目, 因而無法啟動外掛程式。

5. Eclipse 3.0 的並行功能更強

在 Eclipse 3.0 版之前,Eclipse 多半都在單一執行緒上運作。 大部分的 API 方法和延伸點,都是在下列一種執行緒中執行: 一個是 UI 執行緒,另一個是從阻礙 UI 執行緒的進度對話框產生的執行緒。 大部分的外掛程式作者,除了確保所有的 UI 活動都要在 UI 執行緒執行之外,都不必擔心執行緒安全的問題。 一般說來,Eclipse 3.0 版的並行功能遠高於前版。 現在許多作業都是在背景緒執行, 這些作業可以和其他執行緒同時執行,包括 UI 執行緒在內。 只要程式碼是在背景緒執行的外掛程式, 現在都必須注意程式碼的執行緒安全。

除了利用 org.eclipse.core.runtime.jobs API,在背景明確執行作業的外掛程式之外, 還有好幾個平台 API 機能和延伸點都是使用背景緒。 不過,採用這些機能的外掛程式,都必須確保其程式碼沒有執行緒安全的問題。 下表所彙總的 API 和延伸點,其所有或部分的程式碼,都是在 Eclipse 3.0 版的背景緒執行。

延伸點或 API 類別

附註

org.eclipse.core.runtime.IRegistryChangeListener Eclipse 3.0 版的新功能,在背景執行
org.eclipse.core.resources.IResourceChangeListener AUTO_BUILD 事件現在是在背景執行
org.eclipse.core.resources.builders(延伸點) 自動建置現在是在背景執行
org.eclipse.core.resources.ISaveParticipant SNAPSHOT 現在是在背景執行
org.eclipse.ui.workbench.texteditor.quickdiffReferenceProvider(延伸點) Eclipse 3.0 版的新功能,在背景執行
org.eclipse.ui.decorators(延伸點) 已在 Eclipse 2.1 版的背景執行
org.eclipse.ui.startup(延伸點) 已在 Eclipse 2.1 版的背景執行
org.eclipse.team.core.org.eclipse.team.core.repository(延伸點) 有許多作業現在都在背景執行
org.eclipse.team.ui.synchronizeParticipants(延伸點) Eclipse 3.0 版的新功能,在背景執行
org.eclipse.debug.core.launchConfigurationTypes(延伸點) 現在是在背景執行
org.eclipse.jdt.core.IElementChangedListener ElementChangedEvent.PRE_AUTO_BUILD 現在是在背景執行, POST_RECONCILE 早已在背景執行

要讓程式碼沒有執行緒安全的問題,有好幾種策略可用。 原始的解決方案是確保所有的工作都在 UI 執行緒發生,以便將執行作業序列化。 這個方法是針對沒有進行 CPU 密集處理的 UI 外掛程式而設。 在執行這項作業時,請注意 Display.syncExec 所存在的死結風險。 通常 Display.asyncExec 比較安全,因為它沒有死結風險,只是在執行程式碼時,無法精確掌控。

其他確保執行緒安全的方法還有:

6. 針對 IFiles 開啟編輯器

下列方法已經從 org.eclipse.ui.IWorkbenchPage 介面刪除了。 因為 IWorkbenchPage 是在通用工作台宣告,但是下列方法卻是專用於資源的方法。

這些 IWorkbenchPage.openEditor 方法的用戶端, 應該要呼叫在類別 org.eclipse.ui.ide.IDE(在 org.eclipse.ui.ide 外掛程式中)中宣告的對應 public static 方法。

這些 IWorkbenchPage.openSystemEditor(IFile) 方法的用戶端, 應該利用新的 FileEditorInput(IFile),將 IFile 轉換為 IEditorInput, 然後呼叫 openEditor(IEditorInput,String) 方法。 換句話說,就是將 page.openSystemEditor(file) 重寫為 page.openEditor(new FileEditorInput(file), IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID)。 附註:使用編輯器 ID IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID 的用戶端, 必須傳遞實作 org.eclipse.ui.IPathEditorInput(由 FileEditorInput 執行)的編輯器輸入。

附註:這是其中一項不相容的地方,但這一點並影響 Eclipse 3.0 版執行 2.1 版二進位外掛程式的方式。 Eclipse 3.0 版含有二進位執行時期相容性機制, 可以讓使用任何已經刪除之 openEditor 和 openSystemEditor 方法的現有 2.1 版外掛程式二進位檔, 無視於這個 API 變更,繼續以在 2.1 版的方式執行作業。 (已經刪除的方法,是由 org.eclipse.ui.workbench.compatibility 片段有效「加回」)。

7. 編輯器 goto 標記

下面這個方法,已經從 org.eclipse.ui.IEditorPart 介面刪除了。 因為 IEditorPart 是在通用工作台宣告,但是這個方法卻是專用於資源的方法。

對應的方法,也已經從實作 IEditorPart 之 org.eclipse.ui.part 套件中的類別刪除了(亦即 EditorPart、MultiEditor、MultiPageEditorPart 和 MultiPageEditor)。  

呼叫這個方法的用戶端,應該測試編輯器部分是實作還是適應 org.eclipse.ui.ide.IGotoMarker(在 org.eclipse.ui.ide 外掛程式中), 如果要測試,請呼叫 gotoMarker(IMarker)。IDE 類別有一個很方便的方法,可以執行這個動作:IDE.gotoMarker(editor, marker);

實作可以根據 IMarker 資訊為自己定位之編輯器的用戶端, 應該實作或者適應 org.eclipse.ui.ide.IGotoMarker。

由於 IGotoMarker 唯一的方法是 gotoMarker(IMarker), 而且與舊 IEditorPart.gotoMarker(IMarker) 的簽章和規格相同, 因此只要把 IGotoMarker 加到類別定義的實作子句中,現有的編輯器實作就可以適應這項變更了。

具有呼叫這個方法之程式碼的 2.1 版二進位外掛程式, 在標準 Eclipse 3.0 版配置上執行時,會接獲一個類別鏈結錯誤異常狀況。

8. 編輯器啟動程式

編輯器啟動程式介面 org.eclipse.ui.IEditorLauncher 是由提供外部編輯器的外掛程式加以實作。 下面這個方法已經從這個介面移除了。 因為 IEditorLauncher 是在通用工作台宣告,但是這個方法卻是專用於資源的方法。

它已經換成

呼叫 IEditorLauncher.open(file) 的用戶端, 應該要呼叫 IEditorLauncher.open(file.getLocation()) 才對。 實作這個介面的用戶端,應該把 open(IFile) 的實作,換成(或加強)open(IPath) 的實作。

具有呼叫這個方法之程式碼的 2.1 版二進位外掛程式, 在標準 Eclipse 3.0 版配置上執行時,會接獲一個類別鏈結錯誤異常狀況。

9. 編輯器登錄

下列方法已經從 org.eclipse.ui.IEditorRegistry 介面移除了。 因為 IEditorRegistry 是在通用工作台宣告,但是這些方法卻是專用於資源的方法。

呼叫 getEditors(file) 或 getImageDescriptor(file) 的用戶端,應該呼叫相當於 "String" 的方法才對: 呼叫 setDefaultEditor(IFile file, String editorId) 和 getDefaultEditor(IFile file) 的用戶端, 應該呼叫在類別 org.eclipse.ui.ide.IDE(在 org.eclipse.ui.ide 外掛程式中)中宣告的對應 public static 方法: 同時,IEditorRegistrygetDefaultEditor() 方法的 API contract 已經變更了。 這個方法(現在也即將棄用)一定會傳回「系統外部編輯器」的編輯器描述子。 這項變更會影響假設傳回的預設編輯器是文字編輯器的用戶端。

同時,也會有新的常數代表系統外部編輯器和系統原位編輯器 ID(SYSTEM_EXTERNAL_EDITOR_ID 和 SYSTEM_INPLACE_EDITOR_ID)。 這兩個編輯器都需要實作或適應 org.eclipse.ui.IPathEditorInput 的編輯器輸入。 請注意,不支援原位編輯的 Eclipse 配置,就不會有原位編輯器描述子存在。

10. 工作台標記說明登錄

下面這個方法已經從 org.eclipse.ui.IWorkbench 介面刪除了。 因為 IWorkbench 是在通用工作台宣告,但這個方法卻是專用於資源的方法。

IWorkbench.getMarkerHelpRegistry() 的用戶端應該呼叫 Public static 方法 org.eclipse.ui.ide.IDE.getMarkerHelpRegistry()(在 org.eclipse.ui.ide 外掛程式中) 才對。

具有呼叫這個方法之程式碼的 2.1 版二進位外掛程式, 在標準 Eclipse 3.0 版配置上執行時,會接獲異常狀況。

11. 文字編輯器文件提供者

為了讓 org.eclipse.ui.texteditor.AbstractTextEditor 與 IFile 無關, org.eclipse.ui.texteditor.AbstractDocumentProvider 引進了文件提供者作業 (DocumentProviderOperation) 以及文件提供者作業執行器 (IRunnableContext) 的概念。 當 AbstractDocumentProvider 必須執行重設、儲存或同步化作業時, 它會建立文件提供者作業,並且使用作業執行器來執行這些作業。 子類別可以透過 getOperationRunner 方法,提供可以執行的環境定義。 下面就是用戶端必須適應的變更:

AbstractDocumentProvider 的子類別 org.eclipse.ui.editors.text.StorageDocumentProvider 實作 getOperationRunner 方法時,一律傳回空值。這也就是說,StorageDocumentProvider 的子類別,應該不會受到這項變更的影響。

StorageDocumentProvider 子類別 org.eclipse.ui.editors.text.FileDocumentProvider 在實作 getOperationRunner 方法時, 會傳回 IRunnableContext 來執行 WorkspaceModifyOperation 內的 DocumentProviderOperations。 下面是對 FileDocumentProvider 所做的其他變更:

12. 文字編輯器

對 org.eclipse.ui.texteditor.AbstractTextEditor 所做的變更:

AbstractTextEditor 子類別 org.eclipse.ui.texteditor.StatusTextEditor 可以提供 predicate 方法 isErrorStatus(IStatus)。 子類別可以置換,以便決定某個狀態是否必須被視為錯誤。

改為 org.eclipse.ui.editors.text.AbstractDecoratedTextEditor:

13. 無監視器型註釋支援

為了引進無監視器型註釋支援,因此對註釋做了下列變更:

        org.eclipse.jface.text.source.Annotation 
        org.eclipse.jface.text.source.AnnotationModel 
        org.eclipse.jface.text.source.AnnotationModelEvent 
        org.eclipse.jface.text.source.IAnnotationModel 
        org.eclipse.jface.text.source.IAnnotationModelListener 
        org.eclipse.jface.text.source.IAnnotationModelListenerExtension

14. 「主控台」視圖

Eclipse 3.0 版有新的通用主控台支援。 通用主控台可以透過「視窗 > 顯示視圖 > 基本 > 主控台」來使用, 並且由 Eclipse 除錯和 Ant 整合作業所使用。

主控台的視圖 ID,已經從 org.eclipse.debug.ui.ConsoleView 改為 org.eclipse.ui.console.ConsoleView。 由於舊視圖已經不存在了,因此以程式設計方式開啟主控台的 2.1 版外掛程式,是無法使用的。

15. Java 岔斷點接聽器

在 3.0 版中,org.eclipse.jdt.debug.core.IJavaBreakpointListener.breakpointHit(IJavaBreakpoint, IJavaThread) 和 installingBreakpoing(IJavaTarget, IJavaBreakpoint, IJavaType) 方法的傳回類型, 已經從 boolean 改為 int,這是為了讓接聽器提出「無所謂」的決定。 而在 3.0 之前的版本中,接聽器只能夠在到達岔斷點時,決定「暫停」或「不要暫停」, 以及在即將安裝岔斷點時,表決「安裝」或「不要安裝」。 在 3.0 版中,接聽器也可以對上述通知提出「無所謂」的決定。 這麼一來,如果用戶端遇到他們關心的情況時,也可以做出決定性的表決。 岔斷點在接獲「到達岔斷點」的通知時, 如果有任何接聽器決定「暫停」,或者所有的接聽器都決定「無所謂」,它就會暫停; 如果至少有一個接聽器決定「不要暫停」,而且沒有一個接聽器決定「暫停」,則它就不會暫停。 同樣的,在接獲「安裝岔斷點」的通知時, 如果有任何接聽器決定要安裝,或者所有的接聽器都決定「無所謂」,就會安裝岔斷點; 如果至少有一個接聽器決定「不要安裝」,而且沒有一個接聽器決定「安裝」,那就不安裝岔斷點。 除非實作程式堅持某一種做法,否則它應該都會傳回 DONT_CARE。 您一定要記住,舉例來說,「暫停」這個決定,會置換任何其他接聽器的「不要暫停」決定。

IJavaBreakpointListener 介面是由建立或回應 Java 程式碼中之岔斷點的用戶端所實作。 除了 JDT 自己以外,不太可能有其他用戶端, 因此請把報告這項變更所補救的問題(錯誤 37760)的用戶端儲存起來。 這對於實作 IJavaBreakpointListener 介面的現有程式碼來說,是一個很大的改變。 這個程式碼必須修改成傳回適當的 int 值,才能在 3.0 版編譯或執行。

16. UI 執行緒的剪貼簿存取

在 3.0 版之前,SWT 類別 org.eclipse.swt.dnd.Clipboard 上的方法,都是偷偷的在 UI 執行緒以外的執行緒執行。 因此,一旦遇到作業系統要求所有剪貼簿交談作業都要在 UI 執行緒中執行的 GTK 時,這項疏失就會導致失敗。 由於許多應用程式都只有單緒,大部分的測試都是在 Windows 上接收, 因此並沒有及早發現這項疏失。 為了讓剪貼簿 API 得以保持正常運作,並且跨平台使用, 因此在 3.0 版中,所有剪貼簿 API 方法的規格和實作, 已經改為如果從非 UI 執行緒呼叫時,就擲出 SWT 異常狀況 (ERROR_THREAD_INVALID_ACCESS)。 剪貼簿服務一般是由 Eclipse 元件(例如,文字編輯器)自動提供,因此許多用戶端不必採用這項更動。 直接使用剪貼簿的現有程式碼,一定要使用 Display.asyncExec 或 syncExec, 讓 API 方法在正確的執行緒上呼叫(如果可以將存取權轉移到 UI 執行緒的話)。

17. 按鍵懸置事件

在 3.0 版中,SWT 會在 OS 按鍵懸置事件完成之前,先報告按鍵懸置事件。 這個動作比起 3.0 以前的版本要超前許多。 這項變更是為了支援 Eclipse 的按鍵連結, 在任何小組件有機會處理字元之前,必須先截取按鍵事件。 對於直接處理低階 org.eclipse.swt.SWT.KeyDown 事件的程式碼來說,這項改變的結果是可見的。 舉例來說,當文字小組件上的接聽器接獲按鍵懸置事件時, 小組件的內容 (getText()) 尚未包含您剛剛敲擊的按鍵(3.0 版之前是有的)。 如果您要從小組件取得完整的文字(包括目前按鍵在內), 最好是處理較高階的 SWT.Modify 或 SWT.Verify 事件, 而非處理低階的 SWT.KeyDown 事件;不過對於已經用這種方式做這個動作的程式碼而言,則不受影響。

18. 利用 Tab 鍵遍訪的自訂控制項

在 3.0 版之前,如果焦點是在 SWT 類別 org.eclipse.swt.widgets.Canvas 或其中一個子類別(包括自訂的小組件在內)上, 這時按 Ctrl+Tab、Shift+Tab、Ctrl+PgUp 或 Ctrl+PgDn, 就會自動觸發遍訪下一個/前一個小組件的動作,而不報告按鍵事件。 這個行為並未指定,而是執行計數器,讓畫布看得到打在它上面的每一個鍵。 如果要妥善處理遍訪動作,最好是登錄一個遍訪接聽器。 為了妥善支援 3.0 版中的 Eclipse 按鍵連結,預設行為也改了, 現在畫布所看到的是 Ctrl+Tab、Shift+Tab、Ctrl+PgUp 和 Ctrl+PgDn 按鍵事件,而不是遍訪。 如果您使用原始畫布,或者為畫布定義一個子類別,請務必登錄一個遍訪接聽器。

19. SWT 表格和樹狀結構小組件中的選取事件順序

如果您在 SWT 類別 org.eclipse.swt.widgets.Table 和 Tree 中,以滑鼠選擇項目, 則會在所有的作業環境中,統一產生事件序列 MouseDown-Selection-MouseUp。 同樣的,如果您選擇鍵盤,就會在所有的作業環境中,統一產生事件序列 KeyDown-Selection-KeyUp。 在 3.0 版以前,事件的順序並不統一,總是先報告選擇事件, (亦即 Selection-MouseDown-MouseUp 或 Selection-KeyDown-KeyUp),使得 Motif 和 Photon 與其他事件老是不一致。 到了 3.0 版,Motif 和 Photon 的事件順序已經與其他事件一樣了。 雖然在 {Windows, GTK} 和 {Motif, Photon} 上運作正常的現有程式碼,不太可能受到影響, 不過您最好檢查一下程式碼,確保它所採用的事件順序沒錯。

20. 狀態物件中的新嚴重性層次

您可以利用 org.eclipse.core.runtime.IStatus 的新嚴重性常數 IStatus.CANCEL,指出取消作業。 但是,一直採用 IStatus.OKINFOWARNINGERROR 這四項嚴重性的 IStatus.getSeverity() 的呼叫端,就會受到這個新成員的影響了。 getSeverity 的呼叫端應該更新它們的程式碼,讓它新增嚴重性。

21. 與建置相關聯的資源變更通知

在 Eclipse 3.0 版中,工作區自動建置作業是在背景緒執行。 不過,API contract 必須改為 org.eclipse.core.resources.IResourceChangeEventIResourceChangeEvent 的 contract,之前保證所有工作區變更的事件順序如下:

  1. PRE_DELETEPRE_CLOSE 事件通知(如果適用的話)
  2. 執行作業
  3. PRE_AUTO_BUILD 事件通知
  4. 如果自動建置是在開啟狀態,則執行增量工作區建置
  5. POST_AUTO_BUILD 事件通知
  6. POST_CHANGE 事件通知

現在自動建置正在背景執行, 因此不再要保證 AUTO_BUILD 事件和 POST_CHANGE 事件之間的暫時關係。 在 Eclipse 3.0 版中,作業已經移除上述結構中的步驟 3-5。 它所得出的結果如下所示:

  1. PRE_DELETEPRE_CLOSE 事件通知(如果適用的話)
  2. 執行作業
  3. POST_CHANGE 事件通知

平台會定期執行背景工作區建置作業。 請注意,不管自動建置功能是開還是關,都會執行這項作業。 不過,建置作業的確實執行時間並未指定。 建置作業的結構如下所示:

  1. PRE_BUILD 事件通知(PRE_BUILDPRE_AUTO_BUILD 的新名稱)
  2. 如果自動建置是在開啟狀態,則執行增量工作區建置
  3. POST_BUILD 事件通知(POST_BUILDPOST_AUTO_BUILD 的新名稱)
  4. POST_CHANGE 事件通知

自動建置接聽器所接收的差異參照點,與後置變更接聽器不同。 建置接聽器會收到自上次建置作業結束以來,所有變更的通知。 後置變更接聽器則會接收一份差異資料,說明自上次後置變更通知以來,所有的變更。 這個新結構保留了資源變更接聽器自 Eclipse 1.0 版以來就有的三種特性:

不過,這個方法有一些重要的差異。 在 Eclipse 3.0 版之前,自動建置接聽器一定是在 POST_CHANGE 接聽器之前呼叫。 因此,自動建置接聽器所接收的差異,一定是 POST_CHANGE 接聽器所接收之差異的一部分。 這個關係現在剛好顛倒。 自動建置接聽器會接收自從上次背景建置結束以來,所有提供給 POST_CHANGE 接聽器之差異的超集子集。 就像之前一樣,自動建置接聽器還是可以修改工作區,而後置變更接聽器不行。

以前只要工作區變更作業一完成, AUTO_BUILD 事件接聽器就會收到通知,但現在不再是這樣了。 在 IWorkspace.addResourceChangeListener(IResourceChangeListener) 登錄資源變更接聽器的用戶端程式碼, 不太會受到這項變更的影響,因為 AUTO_BUILD 事件從未報告給這些接聽器。 不過,使用 IWorkspace.addResourceChangeListener(IResourceChangeListener,int) 並且指定包括 AUTO_BUILD 事件在內之事件遮罩的用戶端, 如果它們假設自動建置接聽器何時執行,或者它們是在哪一個執行緒執行,就很容易受到這項變更的影響了。 比方說,如果自動建置接聽器配合工作區所做的變更而更新網域模型,則當工作區變更作業傳回時,也許就不會進行這項更新作業了。 請注意,只有 UI 層次的程式碼會在這方面受到影響。 透過 API 加以呼叫的核心層次程式碼, 可以在 IWorkspaceRunnable 範圍內呼叫, 因此它永遠無法知道何時會呼叫資源變更接聽器。 如果在作業完成之前,必需發出通知,則對於這項毀損,我們建議的修正方式是使用 POST_CHANGE,而不是建置接聽器。

22. 在進行工作區作業時所發出的通知

所有在 IWorkspaceRunnable 的動態範圍期間所做的資源變更, 現在不保證可以全部寫在一個通知內。 您仍然可以使用這項機制,將變更的內容批次化, 以避免不必要的建置和通知,不過,現在平台可以決定在作業期間執行通知了。 這個 API contract 變更不太可能成為現有用戶端的重要變更。 它相當於決定在長時間的執行作業期間,定時呼叫 IWorkspace.checkpoint 的平台。 會進行這項變更,是因為現在已經可以有多個執行緒同時修改工作區。 只要其中一個執行緒改完工作區時,就必須發出一個通知,以免發生回應問題, 即使另一個作業尚未完成也一樣。 這麼一來,使用者不必等作業完成,就可以開始處理一組資源了。 比方說,使用者可以開始瀏覽仍然在檢查中的專案檔案。 新的方法 IWorkspace.run(IWorkspaceRunnable, ISchedulingRule, int, IProgressMonitor) 有一個選擇性旗標 AVOID_UPDATE, 作業可以把其當作對平台的暗示,讓平台指定是否需要定期更新。

23. URL 串流處理常式延伸

影響所及:提供延伸給 org.eclipse.core.runtime.urlHandlers 延伸點的外掛程式。

說明:org.eclipse.core.runtime.urlHandlers 延伸點的 contract,已經改用 OSGi 所提供的 URL 串流處理常式服務。 OSGi 支援比 Eclipse 2.1 版的 OSGi 支援更優,它可以正確處理動態處理常式。 由於基本 Java URL 處理常式機制有許多設計問題, 因此在 OSGi 處理常式服務登錄的 URLStreamHandler,必須實作 org.osgi.service.url.URLStreamHandlerService

必須採取的動作:以前,handler 類別必須實作 java.net.URLStreamHandler, 並且延伸 urlHandlers 延伸點。 但是現在已經不再支援延伸點,因此必須更新處理常式,來實作 org.osgi.service.url.URLStreamHandlerService 介面。 OSGi 組織架構可以提供抽象的基本類別(org.osgi.service.url.AbstractURLStreamHandlerService), 這個基本類別可以分成子類別,來填補這個角色。

外掛程式現在不再使用延伸點來登錄處理常式,而是把其處理常式登錄為服務。 例如:

    Hashtable properties = new Hashtable(1);
    properties.put(URLConstants.URL_HANDLER_PROTOCOL, new String[] {MyHandler.PROTOCOL});
    String serviceClass = URLStreamHandlerService.class.getName();
    context.registerService(serviceClass, new MyHandler(), properties);

24. 類別載入順序

影響所及:提供套件的外掛程式(假設其他外掛程式也提供這些套件)。 受到這項變更影響的外掛程式並不多,而且有的影響其實是正面的(如下所示)。

說明:在 Eclipse 2.x 版中,類別載入器會以下列順序搜尋類別: 諮詢 (1) 母類別載入器(其實就是 Java 開機類別載入器), 然後是 (2) 它自己的類別路徑內容,最後是 (3) 以宣告的順序,諮詢所有的必備項目。 OSGi 在這個模型的效果最佳。 採用這個方法時,類別載入器會諮詢 (1) 母類別載入器(同樣的,它其實是 Java 開機類別載入器),然後是諮詢 (2a) 一個必備項目(這個必備項目會提供套件中被查詢的類別),或是諮詢 (2b) 它自己的類別路徑項目,尋找所要的類別。

類別載入器會根據它的匯入和必備套件,決定要諮詢自己,還是它的必備項目。 如果是傳統的外掛程式,這些資訊就是來自外掛程式內容, 如果是具有明確 OSGi 軟體組 Manifest 的外掛程式,則是直接指定。 不管是哪一種情況,它都是一種哪些類別載入器會為哪些套件提供類別的優先順序。 它可以改善效能,並且針對多個提供同樣類別的必備項目,提供問題的解決方案。

以 Xerces 和 Xalan 為例,此二者都含有來自 org.xml 套件的各種類別。 如果是第一種方法,Xerces 外掛程式會看到這些類別的副本,而 Xalan 外掛程式則是看到它們的副本。 由於這些外掛程式需要溝通,因此會產生 ClassCastExceptions。 如果是採用第二種方法,則這兩個外掛程式只有一個會提供重複的類別,但兩者都會看到同樣的副本。

必須採取的動作:要採取什麼動作,其實要根據使用個案的參與者而定。 影響所及的開發人員,必須檢查他們的類別路徑,解析可能發生的衝突。

25. 沒有設定類別載入器保護網域

影響所及:預期要全時設定類別載入器的保護網域的外掛程式。

說明:在 Eclipse 2.1 版中外掛程式類別載入器是 java.security.SecureClassloaders,它本身一定會設定一個保護網域。 而在 Eclipse 3.0 版中,類別載入器不會延伸 SecureClassloader, 因此只有在開啟 Java 安全性功能時(不是一般情況),才會設定保護網域。

必須採取的動作:要採取什麼動作,必須根據外掛程式使用保護網域的實務而定。

26. PluginModel 物件強制轉型

影響所及:將類型 org.eclipse.core.runtime.IPlugin* 之物件強制轉型為類型 org.eclipse.core.runtime.model.Plugin*Model 之物件的外掛程式。 即使 Eclipse 2.1 版的 API 沒有指定這些介面和模型類別之間的關係, 我們還是會明確呼叫這項變更, 因為我們在 2.1 版實作中,發現有使用這個關係的外掛程式實例。

說明:Eclipse API 會提供一系列的介面(例如,IPluginDescriptor), 以及與外掛程式和外掛程式登錄相關、所謂的 "model" 類別(例如,PluginDescriptorModel)。 在 Eclipse 2.1 版的實作中,model 類別碰巧都是實作相關的介面。 在新的 OSGi 型執行時期中,外掛程式登錄已經大幅重做, 以區隔外掛程式的類別載入和必備項目層面,以及延伸和延伸點層面。 Eclipse 3.0 版的執行時期,是無法維護 2.1 版的實作關係。

必須採取的動作:仰賴這種非 API 關係的外掛程式,必須根據它們的使用個案重做程式碼。 如果需要其他詳細資訊,請參閱本文有關建議變更的章節,以及相關類別和方法的 Javadoc。

27. ILibrary 實作不完整

影響所及:使用 org.eclipse.core.runtime.ILibrary 的外掛程式。

說明:新的執行時期是以與 Eclipse 不同且不相容的格式,來維護類別路徑項目。 因此,相容性層無法正確將基礎 OSGi 結構,做成 ILibrary 物件的模型。 執行時期的相容性支援會建立 ILibrary 物件,但是必須假設每一個項目的預設值(但程式庫的路徑除外)。

必須採取的動作:ILibrary 的使用者應該考慮從適當的軟體組, 存取所要的標頭值(例如,Bundle-Classpath) (請參閱 Bundle.getHeaders()), 並且使用 ManifestElement Helper 類別來解譯項目。 如果需要其他詳細資訊,請參閱類別 Javadoc。

28 URL 格式的假設無效

影響所及:假設安裝結構、位置和本端檔案系統等佈置的外掛程式。

說明:諸如 IPluginDescriptor.getInstallURL() 等方法,都會傳回特定格式的 URL。 雖然沒有指定它們的格式,但是許多不同的外掛程式還是會根據現行實作做出假設。 比方說,它們可能會針對結果,預期接獲 file: URL,並且使用 URL.getFile(),並且使用 java.io.File 操作。 到目前為止,這個方法雖然可行,但卻不太可靠。 比方說,如果外掛程式是安裝在 Web 伺服器,則傳回的可能是 http: URL。 新的 Eclipse 3.0 版執行時期更有彈性,而且有更多可能的執行配置 (例如,維護 JAR 中的所有外掛程式,而不是擴大到目錄中)。 也就是說,新的 OSGi 型執行時期並沒有真的中斷 2.1 版 API,只是揭露更多現行外掛程式所做的假設無效。

必須採取的動作:外掛程式作者應該確定, 它們需要存取的資訊,可以透過 getResource()(在類別路徑上)取得, 也可以使用相關的 API,來存取外掛程式的內容(例如,Bundle.getEntry(String))。

29. BootLoader 方法已被移走/刪除

影響所及:從類別 org.eclipse.core.boot.BootLoader 呼叫特定方法的非外掛程式碼。

說明:Static 方法 BootLoader.startup()、shutdown() 和 run() 已被移到 org.eclipse.core.runtime.adaptor.EclipseStarter,這是 OSGi 組織架構的一部分。 這個 API 是 startup.jar 的 main() 以及 OSGi 組織架構/Eclipse 執行時期之間的介面。 如果要重組執行時期,就不能讓這些方法留在 BootLoader。 舊的 BootLoader 類別現在位於執行時期相容性層,而且即將棄用,被移走的方法則被清除,什麼也沒做。

舊的 BootLoader.getRunnable() 沒有被換掉,因為執行時期已經不能再個別取得應用程式了。 現在使用者必須在啟動平台時,指出他們喜歡的應用程式。

必須採取的動作:這個 API 很少人會用(它不能在 Eclipse 外掛程式使用)。 就算要用,程式碼也必須在 EclipseStarter 使用對應的方法。

30. 外掛程式匯出不會自動併入外掛程式的 JAR

影響所及:所有的外掛程式。

說明:在 Eclipse 2.1 版中,外掛程式的 bin.includes 行(來自 build.properties), 不必含有來自 plugin.xml 檔程式庫宣告的 JAR 清單;這些 JAR 是免費加入的。 在 Eclipse 3.0 版中,build.properties 的 bin.includes 區段的檔案清單非常詳盡, 它必須包含在建置或匯出時,外掛程式開發人員想要加入外掛程式中的所有檔案。

必須採取的動作:確保來自 build.properties 檔的 bin.includes 行, 包含所有列在 plugin.xml 檔的 JAR。

31. 重新匯出執行時期 API

影響所及:外掛程式,這些外掛程式會顯示含有來自更改過之執行時期 API 的元素的 API。

說明:許多外掛程式都會顯現含有來自執行時期 API 之元素的 API。 修改過這裡所說明的 Eclipse 3.0 版執行時期之後,用戶端外掛程式必須重新評估它們在 API 的執行時期 API 的用法。

必須採取的動作:這個實務相當少見,因為很少有 Eclipse 執行時期 API 會變更。 用戶端可能得根據實務更改它們的 API,或者繼續使用相容性層。

32. 在平台上剖析方法的外掛程式

影響所及:使用 org.eclipse.core.runtime.Platform.parsePlugins(..., Factory) 的外掛程式

說明:方法 org.eclipse.core.runtime.Platform.parsePlugins(..., Factory) 已經移除了。 與 Factory 引數相關的 API,已經從 org.eclipse.core.runtime 外掛程式, 往上移到 org.eclipse.core.runtime.compatibility 外掛程式(根據執行時期外掛程式而定)。 因此,剖析方法也跟著移走了。

必須採取的動作:這個方法的使用者,在類別 org.eclipse.core.runtime.model.PluginRegistryModel 上應該使用同樣的方法。

33. 由片段所提供的外掛程式庫

影響所及: 在類別路徑上指定程式碼,但卻不提供該程式碼(亦即,JAR 是由片段提供;例如,org.eclipse.swt 外掛程式)的外掛程式。

說明:新的執行時期必須將 plug.xml 檔,悄悄的轉換為 manifest.mf 檔。 方法是執行直接機械式轉換作業,並且分析由外掛程式列出和提供的 JAR。 如果外掛程式在類別路徑指定一個 JAR,但卻不提供該 JAR, 這麼一來就沒有程式碼可以分析,而外掛程式轉換器也無法產生正確的 manifest.mf。

必須採取的動作:這類外掛程式的提供者必須改在外掛程式本身提供適當的 JAR, 或者以手動方式製作/維護 META-INF/MANIFEST.MF 檔,供外掛程式使用。 通常您可以使用 PDE 取得起始 Manifest,然後把它加到適當的 Provide-Package 標頭中,以完成這個動作。

34. 對建置 Script 所做的變更

影響所及:Script(例如,Ant build.xml 檔),它可以定義含有與執行時期相關的 JAR 和類別目錄的類別路徑。

說明:新的執行時期含有一些新的外掛程式和 JAR。 它們是將執行時期重構為可以配置的部分,而加以引進的。 以大部分的執行時期來說,這些變更都是採用透通方式完成。 不過,如果您有自訂的 build.xml(或是類似的)Script, 目前是核對 org.eclipse.core.runtime 來編譯程式碼, 就必須先更新它們,才能正常運作。 一般標準的 Script,在 <javac> 作業中,都含有一個 參照 org.eclipse.core.runtime 外掛程式的類別路徑項目,如下所示:

    ../org.eclipse.core.runtime/bin;../org.eclipse.core.runtime/runtime.jar

執行時期外掛程式會繼續含有大半的原始執行時期程式碼。 不過,執行時期有許多相容性專用的部分,是在相容性外掛程式中 (org.eclispe.core.runtime.compatibility)。 大部分的新執行時期程式碼,都包含在外掛程式集合中 (org.eclipse.osgi.*)。

必須採取的動作:開發人員最好根據自己的需求,加入下列項目,以杜絕編譯錯誤。 下面我們完整列示了所提供的 JAR,一般在編譯使用時,類別路徑只需用到其中一部分。 按照往常一樣,您可以自由決定加入 /bin 目錄。 下面這些項目是藉由提供外掛程式,而以邏輯方式分組:

此外在某些特殊情況下,也必須用到下列 JAR:

更新這類 Script 時,最好也要抓住機會清除(亦即移除)org.eclipse.core.boot 的參照。 這個外掛程式已經作廢,不再含有任何程式碼。 雖然這些項目可以留在類別路徑,但是它們已經毫無用處,不妨移除算了。 請移除:

    ../org.eclipse.core.boot/bin;../org.eclipse.core.boot/boot.jar

35. 對 PDE 建置 Ant 作業所做的變更

影響所及:使用 eclipse.buildScript 作業的 Script(例如,Ant build.xml 檔)。

說明:PDE 建置引進新內容給 eclipse.buildScript 作業,讓它控制外掛程式建置 Script 的產生。 這項作業是藉著新 OSGi 型執行時期的引進,而委任完成。

必須採取的動作:如果您要使用 Eclipse 3.0 來建置 2.1 版型的產品, 只要在 eclipse.buildScript 引進 "buildingOSGi" 內容,再將它設為 false 即可。 比方說:

<eclipse.buildScript ... buildingOSGi="false"/>

36. 對 eclipse.build Ant 作業所做的變更

影響所及:使用 eclipse.buildScript 作業的 Script(例如,Ant build.xml 檔)。

說明:PDE 建置引進新內容給 eclipse.buildScript 作業,讓它控制外掛程式建置 Script 的產生。 這項作業是藉著新 OSGi 型執行時期的引進,而委任完成。

必須採取的動作:如果您要使用 Eclipse 3.0 來建置 2.1 版型的產品, 只要在 eclipse.buildScript 引進 "buildingOSGi" 內容,再將它設為 false 即可。 比方說:

<eclipse.buildScript ... buildingOSGi="false"/>

37. 對 eclipse.fetch Ant 作業所做的變更

影響所及:使用 eclipse.buildScript 作業的 Script(例如,Ant build.xml 檔)。

說明:PDE 建置改變了 eclipse.fetch 作業的行為, 來簡化自動化建置樣式中的建置 Eclipse。 現在,元素樣式一次只支援一個項目,scriptName 則一律略過不管。

必須採取的動作:如果 eclipse.fetch 呼叫的 "elements" 標示中有一份項目清單, 請分批呼叫 eclipse.fetch,將它們散布出去。 如果您習慣設定 scriptName,請注意,所產生的提取 Script 一律稱為 "fetch_{elementId}"。 比方說:

<eclipse.fetch elements="plugin@org.eclipse.core.runtime, feature@org.eclipse.platform" .../>

變成

<eclipse.fetch elements="plugin@org.eclipse.core.runtime" .../>
<eclipse.fetch elements="feature@org.eclipse.platform" .../>

38. 置換 install.ini

現在已經沒有 install.ini 檔了。 原來在它配置子目錄的位置,現在已經換成新的 config.ini 檔了。 過去使用 install.ini 檔來指定主要特性(例如,提供品牌行銷資訊)的產品,現在則必須修改 config.ini 檔。 除了新檔名之外,還改了按鍵名稱。

2.1 版中的 feature.default.id 鍵值,應該設為新 eclipse.product 鍵的值。 eclipse.application 的值則應該設為 "org.eclipse.ui.ide.workbench"。

最後,在 2.1 版中,splash 影像的影像,在品牌行銷外掛程式的目錄下,一律為 splash.bmp。 在 3.0 版中,splash 影像的位置,是由 config.ini 檔中的 osgi.splashPath 按鍵明確提供。