Eclipse 3.1 和 3.2 在對外掛程式的影響上,有了不相容的改變。 下列項目說明變更的區域,並提供將 3.1 外掛程式移轉至 3.2 的指示。 請注意,如果您無法在 3.2 上執行 3.1 外掛程式,您只需要查看以下指示。
影響對象:假設資源儲存在本端檔案系統的 IWorkspace
API 用戶端。
說明:在 Eclipse 3.2 之前,在 java.io.File
所能存取的檔案系統中,每個現有的 IResource
都有對應的檔案或目錄。
Eclipse 3.2 增加了新支援,所建立的資源能夠將內容儲存在任何支持的檔案系統中。
java.io.File 已無法直接代表使用這項支援的資源。
所需的動作:舊的 IResource.getLocation() 方法會傳回資源的本端檔案系統路徑。 如果資源不是儲存在本端檔案系統中,這個方法會傳回空值。 getLocation() 的大部分呼叫端先前都這麼做,以便取得 java.io.File 的實例,但這個實例已無法用在本端檔案系統所未儲存的資源上。
新的 org.eclipse.core.filesystem 外掛程式提供了一般的檔案系統 API,以便取代 java.io.File。 尤其是,org.eclipse.core.filesystem.IFileStore 的實例也提供了 java.io.File 所提供的大部分相同的方法。 下列程式碼片段含有給定資源的 IFileStore 實例:
IResource resource = ...;//some resource IFileStore store = EFS.getStore(resource.getLocationURI());
下表提供通常是利用 java.io.File 來完成的作業,在 IFileStore 上的對等方法:
java.io.File | IFileStore |
---|---|
delete | delete |
getName | getName |
getParent | getParent |
list | childNames |
mkdir | mkdir(EFS.SHALLOW, null) |
mkdirs | mkdir(EFS.NONE, null) |
renameTo | move |
new FileInputStream(file) | openInputStream |
new FileOutputStream(file) | openOutputStream |
在 IFileStore API 中,檔案的大部分資訊都儲存在藉由呼叫 IFileStore.fetchInfo() 來取得,稱為 IFileInfo 的結構中。 這項設計可讓您利用 java.io.File 來進行更大規模的程式碼最佳化,許多關於檔案的屬性,通常都可以利用單一檔案系統呼叫來取得。 請注意,如果基礎檔案有了改變,IFileInfo 中的資訊會成為太舊,因此,只應在必要之時,才保持實例。 以下是在 java.io.File 上的一些方法,它們在 IFileInfo 上有對等的方法:
java.io.File | IFileInfo |
---|---|
canWrite | isReadOnly |
exists | exists |
getName | getName |
isDirectory | isDirectory |
isFile | !isDirectory() |
isHidden | isHidden |
lastModified | getLastModified |
length | getLength |
setLastModified | setLastModified |
setReadOnly | setAttribute(EFS.ATTRIBUTE_READ_ONLY, true) |
作為具體的範例,先前呼叫 java.io.File.exists() 的程式碼,現在可以呼叫 IFileStore.fetchInfo().exists()。 當修改 IFileInfo 時,必須利用 IFileStore.putInfo 方法來重新存回結果。 例如,這個片段會翻轉檔案的唯讀屬性
IFileStore store = ...;//某個檔案儲存庫 IFileInfo info = store.fetchInfo(); boolean readOnly = info.getAttribute(EFS.ATTRIBUTE_READ_ONLY); info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, !readOnly); store.putInfo(info, EFS.SET_ATTRIBUTES, null);
如同 getLocation() 方法,專案說明的位置不會再出現在本端檔案系統中。 IProjectDescription.getLocationURI() 方法可用來取得資源在任意檔案系統中的位置。
有些用戶端絕對需要檔案的本端表示法。 例如,它們可能會針對這個檔案來啟動原生工具,或使用只能處理檔案系統資源而無法感知 Eclipse 的程式庫(如 java.util.zip.ZipFile)。 在這些情況下,您可以要求 IFileStore 傳回其內容的快取本端副本:
IFileStore store = ...;//某個檔案儲存庫 //看它是否能夠直接以本端檔案來表示 java.io.File local = store.toLocalFile(EFS.NONE, null); //如果不能,便要求檔案的快取本端副本 if (local == null) local = store.toLocalFile(EFS.CACHE, null);
請注意,在取得檔案的快取副本卜之後,它不會與原來的實際檔案系統保持同步。 修改快取的副本,並不會造成修改基礎檔案。
無法處理本端檔案系統外之資源的用戶端,仍可能想改寫程式碼,使失敗顯得溫和一些。 用戶端可以檢查資源是否在本端檔案系統中,當發現它們無法處理的資源時,便忽略資源,或向使用者發出警示。 如果要判斷資源是否在本端檔案系統中,您必須瞭解它的檔案系統架構。 您可以依照下列方式,從資源取得這項資訊:
IResource resource = ...;//某項資源 URI uri = resource.getLocationURI(); if (uri != null && EFS.SCHEME_LOCAL.equals(uri.getScheme())) { //檔案在本端檔案系統中 } else { //檔案不在本端檔案系統中 }
如果您有現成的 IFileStore 實例,您可以依照下列方式來取得架構:
IFileStore store = ...;//檔案儲存庫 store.getFileSystem().getScheme();
影響對象:呼叫 MultiPageEditorSite.progressStart()
或 MultiPageEditorSite.progressEnd()
的用戶端。
說明:在 Eclipse 3.0 版開發期間,加入了這些方法,成為進度支援工作的一部分。 在 3.0 版之前,處理進度的方式有了改變,已不再需要這個方法。 由於程式設計師錯誤,這些公用方法便留給 3.0 版。 這兩個方法不曾在 Eclipse 版本中提供任何功能,因此,已被刪除。
所需的動作:呼叫 MultiPageEditorSite.progressStart()
或 MultiPageEditorSite.progressEnd()
的用戶端應該改用 IWorkbenchSiteProgressService
。
影響對象:自訂了 config.ini,且將他們的應用程式移至 3.2 的用戶端。
說明:在 3.2 之前,config.ini 所包含之 osgi.bundles 的典型的值是 org.eclipse.core.runtime@2:start, org.eclipse.update.configurator@3:start
。
由於執行時期重構,這個值需要更新,應用程式才能順利啟動。
所需的動作:請變更 osgi.bundles 的值,使它包括 org.eclipse.equinox.common@2:start, org.eclipse.update.configurator@3:start, org.eclipse.core.runtime@start
。
影響對象:部署 RCP 應用程式且指定了 osgi.bundles 的用戶端。
說明:在 3.2 之前,主要 JNLP 檔所包含之 osgi.bundles 的典型的值是 org.eclipse.core.runtime@2:start, org.eclipse.update.configurator@3:start
。
由於執行時期重構,這個值需要更新,否則,可能會擲出 NullPointerException
,使應用程式無法啟動。
所需的動作:請變更 osgi.bundles 的值,使它包括 org.eclipse.equinox.common@2:start, org.eclipse.update.configurator@3:start, org.eclipse.core.runtime@start
。
影響對象:呼叫 Bundle.start()
的用戶端。
說明:在 Eclipse 中,軟體組是利用 Eclipse-LazyStart
標頭(或已淘汰的 Eclipse-AutoStart
標頭)指定為延遲啟動軟體組。
在 Eclipse 3.1 中,org.osgi.framework.Bundle.start()
方法並不會將延遲啟動軟體組標示為持續啟動。
由於延遲啟動軟體組絕不會標示為持續啟動,因此,當重新啟動 Eclipse 時,不會自動啟動它們。
Bundle.start()
的 Javadoc 指出當呼叫這個方法時,可能會出現下列情況:
"持續記錄已啟動這個軟體組。 當「架構」重新啟動時,必須自動啟動這個軟體組。"
在 Eclipse 3.2 中,已修正 Bundle.start()
方法,會將軟體組適當標示成持續啟動,即使軟體組是延遲啟動軟體組,也是如此。
這個修正程式必須符合「OSGi 架構」規格。
因此,Bundle.start()
的呼叫端會在 Eclipse 重新啟動時,強制啟動軟體組。
一般而言,這算是不好的做法,因為每次啟動 Eclipse 時,都會造成啟動不必要的軟體組。
在某些情況下,它可能會造成非預期的結果,如錯誤 134412。
所需的動作:Bundle.start()
的用戶端必須評估自己是否意圖每次重新啟動,都持續啟動軟體組。
如果不想如此,用戶端應該尋找另一個方式來啟動軟體組。
在大部分情況下,只要從目標軟體組載入類別時,容許延遲啟動目標軟體組,就可以避免呼叫 Bundle.start()
。
很少有實務需要積極啟動延遲啟動軟體組,但不將這個軟體組標示成在重新啟動時啟動。
這些實務類型應該不要呼叫 Bundle.start()
,而是利用 Bundle.loadClass()
來從必須啟動的軟體組載入類別。
在 Eclipse 3.0 中,既不支援,也不強制在版本 ID 限定元區段使用底線 ('_') 字元。
如果外掛程式版本 ID 的限定元包含底線,當外掛程式匯出到檔案系統中,以及從更新網站安裝外掛程式時,這個字元都會轉換成連字號 ('-')。
在 Eclipse 3.1 中,放寬了限定元容許字元的規則,併入了底線字元,因此,當匯出或安裝不適當的外掛程式時,不會修改限定元的原始狀態。
3.0 至 3.1 的移轉手冊遺漏了這項細緻的變更。
對於 Eclipse 3.2,我們仍在維護與 Eclipse 3.1 的相容性,當處理舊的外掛程式版本時(匯出之時,以及它們存在於更新網站之時),版本限定元含有底線字元的外掛程式應該知道前面提到的變更。
這表示,例如,當外掛程式提供者有舊版的外掛程式在更新網站中,便應該確定檔案系統中的名稱符合外掛程式的名稱。