利用 OSGi 解決 Eclipse 外掛程式難題

2021-05-02 13:38:18 字數 4402 閱讀 5240

本文介紹如何在**中為其他外掛程式編寫擴充套件,而不是用 eclipse v3.2 的動態擴充套件 api 建立對其他外掛程式的依賴性。可使用開放服務閘道器協議 (open services gateway initiative,osgi) 服務 api 和動態 api 完成所有這些任務甚至更多工。
本文介紹了乙個採用 xml 的外掛程式示例,以便為定義好的擴充套件點註冊擴充套件。通過使外掛程式能夠感知 extention registry 並提供 osgi 服務,我們可以完成這一完整的元件退耦操作。

外掛程式、擴充套件點、osgi

如您所知,eclipse 的元件架構是基於外掛程式 的 -- 這意味著將一組**元件化為單一的元件,然後利用 eclipse 框架註冊為其元件之一,其他元件可以繫結該元件或呼叫該元件。擴充套件點 是外掛程式允許其他外掛程式向公開擴充套件點的外掛程式提供附加功能的方法。現在利用所有這些外掛程式並將其包裝到受控的執行時,外掛程式可在其中動態進出,並且您可以獲得 osgi(基本上來說)。

示例外掛程式

讓我們從公開擴充套件點的基本外掛程式開始,這樣可以為同義詞服務註冊新的字串對映。此項服務允許其他服務註冊乙個詞並將其對映到另乙個詞(同義詞)。基本擴充套件包含非常簡單的元素:乙個詞,當然還有乙個新的同義詞。此外掛程式擴充套件點的基本結構如表 1 所示。

表 1. 示例外掛程式的元素

外掛程式名稱

com.company.synonymregistry

擴充套件點同義詞

元素詞 -- 您想要為其新增同義詞的詞

同義詞 -- 您想要註冊的同義詞

我們還要將外掛程式註冊為 osgi 服務。這意味著它只在顯式執行此操作時被載入,並將可供其他客戶宣告性地使用。為了使用該服務,其他客戶只需了解 inte***ce 和 osgi 類名稱。在我們的示例中,我們不會真正呼叫該服務,因為擴充套件點是假設的。我們將使用 osgi api 以告知我們此項服務出入的時間,所以我們可以正確地註冊擴充套件點。

現在這只是乙個示例,並且使用針對此概念的擴充套件點可能不是最好的方法。我們用此基本示例要達到的目的是如何動態註冊新的擴充套件,同時說明使用 osgi api 的外掛程式生命週期事件。

mediator 外掛程式

下乙個外掛程式是第三方外掛程式,該外掛程式了解已知的服務和擴充套件點,但不想繫結到此外掛程式,因為後面它將依靠該外掛程式進行執行時解析。這意味著該外掛程式可以駐留在所引用的外掛程式 (com.company.synonymregistry) 可能不存在的機器上。因為我們現在生活在 osgi 和動態執行時世界,所以我們想確保外掛程式在不引起執行時故障或錯誤的情況下執行。我們的 mediator 外掛程式將接受同義詞的 xml 檔案,並且通過使用提供的擴充套件點用 synonymregistry 外掛程式註冊每個同義詞。

清單 1. 用於概念驗證的示例 xml 檔案

synonyms.xml

<?xml version="1.0" encoding="utf-8"?>

mediator 外掛程式在其start()方法中做的第一件事是用 osgi 服務註冊為乙個服務初始化偵聽器。我們要在傳入start()方法的 bundlecontext 物件上呼叫 osgi 服務方法addservicelistener()。以下**展示了乙個通過傳入**和我們感興趣的服務 id 呼叫此 api 的示例。

context.addservicelistener( this, "com.company.synonymregistry" );

通過提供過濾器,可以告知 osgi 服務註冊中心只需通知您指定服務中的狀態更改。在本例中,過濾器只是 synonymregistry 類的類名稱。

您可能會尋根究底。答案就在啟動序列中。在 osgi 領域,我們不是總知道另一服務可用的時間,因此我們需要對此進行說明。通過註冊為服務偵聽器,我們可得知服務開始和停止的時間。如果服務不可用,則允許我們快取同義詞。當服務確實可用時,我們會得到通知並註冊擴充套件。

註冊新擴充套件

下面我們將講述本文的核心內容。現在我們有了想為其提供動態擴充套件的資料 (synonyms.xml) 和已知的擴充套件點 (com.company.synonymregistry. synonym)。由於我們不知道何時初始化外掛程式,也不知道是否初始化 synonym 外掛程式,所以我們只要在載入外掛程式時嘗試註冊 xml 檔案中的條目即可。請記住:這是乙個展示概念的示例,不應在生產**中這樣實施。通常,我們盡可能多地以惰性方式(延遲或在需要時)執行初始化。

eclipse v3.2 中的新特性是能夠在執行時提供擴充套件。例如,客戶可以編寫乙個包含某個檢視的應用程式,該檢視可以在單擊按鈕時建立乙個透檢視。透檢視被新增到擴充套件登錄檔,然後在可用透檢視的列表中顯示。此功能的重要好處之一是它可以減輕外掛程式之間的「硬」依賴性。外掛程式 a 可供在外掛程式 b 中定義的平台使用,無需依賴外掛程式 b。而且,通過將此功能與 osgi 框架結合,外掛程式可以檢查服務的存在性,如果存在,可從服務中定義的擴充套件點建立擴充套件。這在使用面向服務架構的原則同時,促進了真正動態的環境。

eclipse v3.2 中新公開的是addcontribution()方法,該方法在iextensionregistry介面中定義。清單 2 中的**展示了可以通過addcontribution()api 新增擴充套件的方法。addcontribution()方法旨在採用普通 xml 作為第乙個引數中的inputstream

清單 2. 通過 addcontribution() api 新增擴充套件的方法

iextensionregistry registry = registryfactory.getregistry( );

object key = ((extensionregistry) registry).gettemporaryusertoken( );

bytearrayinputstream is =

new bytearrayinputstream( buffer.tostring().getbytes() );

try

finally catch (ioexception e)

}

編寫本文的時候 -- 意味著這是乙個更改 eclipse 未來版本的好機會 -- 允許公眾訪問登錄檔的使用者標記可以使用此內部 eclipse 呼叫獲得。下面的**展示了內部 api (gettemporaryusertoken()) 的使用。

object key = ((extensionregistry)registry).gettemporaryusertoken();

-declipse.registry.nulltoken=true

此定義現在允許我們將null用作addcontribution()api 中的 user token。現在,我們的**看上去類似如下。有關此問題中的 bugzilla 對話,請參見 bugzilla bug 清單

清單 3. gettemporaryusertoken()

...

try

...

上面顯示的緩衝區變數表示實際的 xml 塊。此 xml 是我們可以在 plugin.xml 檔案內看到的精確副本。回到我們的 synonymregistry 示例,此擴充套件的 xml 將類似清單 4。

清單 4. synonymregistry 的 xml

客戶可以考慮建立乙個接受以下引數的包裝工廠類,如擴充套件點 id、擴充套件 id、元素名稱(本例中是同義詞)、實際屬性和資源包 id。該包裝類將引數格式化為類似上面**的 xml 字串。然後將此 xml 字串讀入將被傳入到iextensionregistry介面的addcontribution()方法的bytearrayinputstream中。只有此方法的其他必需引數是使用者標記和資源包 id。值得注意的一點是,資源包 id 應是做出該貢獻的資源包的 id,不是在其中定義擴充套件點的資源包的 id。

警告和提示

在 m5(於 2006 年 2 月 17 日構建的 eclipse)中引入的乙個特性是,對addcontributions()的呼叫是非同步呼叫。這意味著該擴充套件不可立即使用,因為 eclipse 啟動了一項執行實際註冊的作業。簡單地說,您必須開始自己的作業並與之同步,以獲得任何型別的同步行為。

當然,現在我們必須將呼叫**與生成的作業結合起來,以獲得同步呼叫。這只有在**要求立即使用擴充套件時才得到保證。希望您的**設計為惰性,這樣初始化就變得不重要。

結束語動態擴充套件的使用可以通過程式設計方式建立。通過使用 osgi 框架偵聽服務何時可用(載入或解除安裝),動態擴充套件增強了退耦功能。一起使用這些技術將允許宣告性的貢獻和元件之間 100% 退耦。

解決eclipse卡死問題

jvm調優建議 1.xms xmx 定義young old段的總尺寸,xms為jvm啟動時young old的記憶體大小 xmx為最大可占用的young old記憶體大小。在使用者生產環境上一般將這兩個值設為相同,以減少執行期間系統在記憶體申請上所花的開銷。2.xx newsize maxnewsi...

osgi服務報錯以及相應的解決方法

自己在專案中配置相關的osgi服務,然後不能正常啟動,首先是看容器的日誌,日誌報錯如下 第二種情況就是要依賴的元件沒有想外提供服務,導致他不能使用該元件的服務,修改如下則可以 com.gzydt.license.base.persist,com.gzydt.license.base.persist....

利用Eclipse整合開發環境進行ROS開發

可以利用eclipse整合開發環境進行ros開發,從而提高研發效率。以色列巴爾伊蘭大學的mr.roi yehoshua開設了一門ros課程,課程2 lesson 2 講解了如何利用eclipse在ros上進行開發。這裡走下總結整理。安裝步驟如下 1.安裝eclipse sudo apt get in...