探索 Eclipse 的 OSGi 控制檯

從 V3.0 開始,Eclipse 經過選擇開放服務網關協議(Open Services Gateway Initiative,OSGi)來替換先前版本中不穩定的 Eclipse 插件技術,從而實現了一次巨大飛躍。此次轉變對於用戶來講幾乎是透明的,由於如今所使用的插件的安裝和操做看上去和之前的插件沒有什麼不一樣。 shell

圖 1. Eclipse 內的插件
Eclipse 內的插件

由 於 Eclipse 如今是在 OSGi 上構建的,所以咱們在圖 1 中看到的插件是功能完整的 OSGi 包。(圖 2 顯示了使用 OSGi 控制檯運行 Eclipse 實例內的包。)經過使用 OSGi,Eclipse 支持業內承認的開放標準而且如今能夠利用 OSGi 提供的功能,包括安全性、HTTP 服務、用戶管理和其餘功能。Eclipse 對 OSGi 的使用已經見到成效,由於咱們看到插件間報告的衝突在減小而 Eclipse 的應用在持續增長。 apache

圖 2. Eclipse 內的 OSGi 包
Eclipse 內的 OSGi 包

Eclipse、Equinox、OSGi,天哪!

OSGi Alliance 是一個獨立的、非盈利性組織,負責 OSGi 技術,相似於 Eclipse Foundation 的職能。OSGi Alliance 負責制定描述 OSGi 技術的規範。簡言之,OSGI 技術爲應用程序開發提供了一種面向服務的基於組件的平臺。各類實現都是基於這些規範的。最多見的一個實現是 Equinox,它是 Eclipse 的規範實現。OSGi 的另外一個常見實現是 Apache 的 Felix 項目。 安全

在咱們繼續以前,本文假定您具備 Eclipse 和 OSGi 方面的工做經驗。若是不具有的話,建議先閱讀 Scott Delap 的文章 「瞭解 Eclipse 插件如何使用 OSGi」,而後再來研究 OSGi 控制檯。 app

建立 OSGi 包

此次冒險的第一步是使用 插件開發環境(Plug-in Development Environment,PDE)在 Eclipse 中建立一個簡單的 OSGi 包。爲此,須要使用 PDE 建立一個新的插件項目(File > New > Project > Plug-in Project)。在建立新的插件項目的過程當中,確保設定正確的選項。首先,選擇插件目標平臺做爲 OSGi Framework,具體來講就是 Equinox。最後,爲了簡短起見,使用 PDE 提供的 Hello OSGi Bundle 模板(參見圖 3)。咱們如今建立好了將在本文中使用的包。 框架

圖 3. PDE Hello OSGi bundle 嚮導
PDE Hello OSGi bundle 嚮導

回頁首 eclipse

Hello OSGi 控制檯

如今咱們已經有了本身的 Hello 包,能夠繼續並啓動框架以得到 OSGi 控制檯。要啓動框架,咱們能夠利用 PDE 的 OSGi Framework 啓動配置。首先,轉至啓動配置菜單(Run > Run ...)併爲 Hello 包建立一個 OSGi Framework 啓動配置(參見圖 4)。此外,確保僅選擇運行 Hello 包所需的必要的包。完成此操做的一種簡單方法是在啓動配置中按 Deselect All 鍵並選中 Hello 包,接下來按 Add Required Plug-ins 鍵。 ide

圖 4. PDE 的 OSGi Framework 啓動配置
PDE 的 OSGi Framework 啓動配置

插件和包:有何區別?

每當走過 Eclipse 開發人員的彙集地,您總會聽到人們在談論着兩個有魔力般的字眼:插件。 二者有區別麼?在營銷副總裁看來,兩個術語是同義的。包是插件,插件就是包。咱們彷佛一直在交替地使用這兩個術語。可是,從專業的視角來看,事情並不是如 此。準確地說,Eclipse 插件是利用擴展註冊表的 OSGi 包(即,包的根目錄中有 plug-in.xml)。而 OSGi 包就是 OSGi 包。 測試

完成啓動配置並準備就緒以後,可使用啓動配置對話框中的 Run 按鈕來啓動咱們的包。完成後,應當會看到相似圖 5 的結果。 ui

在圖 5 中,咱們看到 Hello 包已啓動(使用控制檯中打印的 HelloWorld 消息,表示包已被啓動)而且看到osgi>提示符。OSGi 提示符相似於 DOS 或者 Bash 提示符,能夠在提示符處輸入對 OSGi 實例起做用的命令。在本例中,發出ss命令,該命令將快速顯示全部內容的狀態。建議您在普通的 Eclipse 實例中嘗試此命令,將發現全部內容只不過是隱藏着的一個 OSGi 包。要得到普通 Eclipse 實例的 OSGi 控制檯,只需用-console參數啓動 Eclipse。 this

圖 5. 首次啓動
首次啓動

啓動和中止包

在 OSGi 動態環境中,能夠輕鬆地啓動和中止包。要測試此操做,讓咱們使用簡單的 Hello 包。只需用stop命令便可中止包,而後用start命令啓動包。您應當會看到相似圖 6 的結果。

圖 6. 啓動和中止包
啓動和中止包

添加、刪除和更新包

OSGi 系統的另外一個強大的方面是可以在運行的 OSGi 實例中添加、刪除和更新包 —— 全部操做均無需從新啓動 Java™ 虛擬機。圖 7 演示了包的安裝和卸載。

圖 7. 安裝和卸載包
安裝和卸載包

錯誤診斷

有時在包或插件嘗試啓動的初始化過程當中會發生錯誤。OSGi 控制檯提供了一個有用的命令 ——diag—— 能夠幫助您調試與包初始化相關的問題。例如,讓咱們來檢驗一下圖 8,在嘗試啓動 Hello 包時,得到一個錯誤。爲了幫助診斷錯誤,對包運行diag命令並將看到運行時環境中缺乏一個導入包。

圖 8. 控制檯錯誤診斷
控制檯錯誤診斷

有用的控制檯命令摘要

表 1. 有用的控制檯命令
命令 描述
start 啓動給定了 ID 或符號名稱的包
stop 中止給定了 ID 或符號名稱的包
install 爲當前實例添加一個給定了 URL 的包
uninstall 刪除當前實例的具備給定 URL 的包
update 爲當前實例更新給定 URL 的包
active 列出當前實例中全部活動的包
headers 列出具備給定 ID 或符號名稱的包的標頭
ss 列出在當前實例中註冊的全部包的簡短狀態
services <filter> 列出給定了正確過濾器的服務
diag 在給定 ID 或符號名稱的包上運行診斷程序

還有不少其餘 OSGi 命令可用。這裏列出的命令是我認爲最有用的命令。要得到全部命令的列表,只需在控制檯中鍵入help。

回頁首

擴展控制檯

人們說 Eclipse 的絕妙之處就在於它的可擴展性。控制檯是以相似方式擴展的。這是十分重要的,由於做爲一名開發人員,您可能向用戶提供某種服務。經過擴展控制檯,您可使高級用戶或管理員可以調試關於服務的問題。

控制檯不使用熟悉的擴展點,它具備一種簡單的可擴展性機制。讓咱們經過幾個示例來講明控制檯的可擴展性。

uname,OSGi 樣式

使用過 UNIX® 風格的系統的人都會熟悉uname命令,該命令將打印關於運行的操做系統的名稱、版本和其餘信息。在 OSGi 上下文中,有各類不一樣風格的 UNIX 的方法就能夠有 OSGi 控制檯的不一樣實現(例如 Apache FelixKnopflerfish 等等)。

擴展 OSGi 控制檯的最重要部分是CommandProvider接口。但願擴展控制檯的客戶機必須實現此接口。實現此接口後,下一步是啓動帶有"_"的方法名稱。這些方法將表示控制檯中可用的命令。就這麼簡單!參見清單 1 中的示例。

清單 1. OSGi uname
public class Activator implements BundleActivator, CommandProvider {

	private BundleContext context;

	public void start(BundleContext context) throws Exception {
		this.context = context;
		Hashtable properties = new Hashtable();
		context.registerService\
		(CommandProvider.class.getName(), this, properties);
	}

	public String getHelp() {
		StringBuffer buffer = new StringBuffer();
		buffer.append("\tuname - returns framework information\n");
		return buffer.toString();
	}

	public void stop(BundleContext context) throws Exception {}
	
	public void _uname(CommandInterpreter ci) throws Exception {
		String vendor = context.getProperty(Constants.FRAMEWORK_VENDOR);
		String version = context.getProperty(Constants.FRAMEWORK_VERSION);
		String osName = context.getProperty(Constants.FRAMEWORK_OS_NAME);
		String osVersion = context.getProperty(Constants.FRAMEWORK_OS_VERSION);
		System.out.println("\n " + vendor + " " 
				+ version + " (" + osName + " " 
				+ osVersion + ")");
	}
}

包和存在主義

包自己可能從未質疑過本身的存在,這裏提供了一個簡單示例,它將打印出一個包是 vanilla 包仍是 Eclipse 插件。(記住,二者都仍是包!)清單 2 經過添加新方法並修改getHelp()方法來構建先前的示例。

清單 2. 修改getHelp()
...
public String getHelp() {
		StringBuffer buffer = new StringBuffer(); buffer.append("\twhatami - \ returns whether the bundle is a plug-in or not\n"); buffer.append("\tuname - returns framework information\n");
		return buffer.toString();
	}
	
public void _whatami(CommandInterpreter ci) throws Exception {
		try {
			long id = Long.parseLong(ci.nextArgument());
			Bundle bundle = context.getBundle(id);
			URL url = bundle.getEntry("plugin.xml");
			if(url != null) {
				System.out.println("\n I'm \
				(" + bundle.getSymbolicName() + ") a plug-in");
			} else {
				System.out.println("\n I'm \
				(" + bundle.getSymbolicName() + ") not a plug-in");
			}
		} catch (NumberFormatException nfe) {
			System.out.println("\n Error processing command");
		}
	}
...

圖 9 中顯示了咱們的工做結果。

圖 9. 擴展控制檯的結果
擴展控制檯的結果

回頁首

結束語

本 文演示瞭如何使用 OSGi 控制檯以及如何擴展控制檯。在此過程當中,咱們查看了控制檯以及如何擴展控制檯的幾個示例。您如今已經更加熟悉控制檯而且知道了如何在平常的 Eclipse 開發中使用控制檯。使用控制檯可能甚至會讓您回想起玩 Doom and Quake 時的情景。

圖 10. Quake 控制檯
Quake 控制檯
相關文章
相關標籤/搜索