歡迎回到EclipseZone的OSGi系列課程來!這是我們的第二次課——“與OSGi框架進行交互”
上節課我們看了一個簡單的Hello World Bundle,它在啓動和停止的時候打印了一些信息。它繼承了接口BundleActivator,並且實現了start和stop方法。我們來再看一下代碼。特別是start方法和stop方法的實現,你是否注意到我們在方法裏傳入了一個參數——BundleContext。在這次的課程裏,我們就來看一下BundleContext,以及我們可以用它來做什麼。
BundleContext是OSGi框架送給我們的Bundle的一張不可思議的門票。當我們需要同OSGi框架進行交互的時候,我們需要使用BundleContext。事實上,這是唯一同OSGi的API進行交互的途徑。並且OSGi框架對每一個Bundle發放了門票,以便每一個Bundle在啓動的可以通過BundleActivator與框架進行交互。
如果你的Equinox也就是OSGi並沒有停止的話,那你不需要啓動它。如果它沒有運行,請記住啓動使用個這個命令將它啓動(現將工作目錄轉移到OSGi測試目錄裏,詳細請看第一部分)。
java -jar equinox.jar -console
根據提示符輸入“ss”,然後你將會看到上次已經安裝的Hello World Bundle。即使你已經關閉了OSGi服務並且又啓動了它,你依然會看到這個情況。這是因爲OSGi框架會自動將它的啓動到運行的狀態保留在配置文件中。爲了證明這個,我們將寫一個Bundle,這個Bundle將會自動尋找並且卸載Hello World Bundle。我們可以在控制檯裏使用“uninstall”命令輕鬆的實現這個功能。並且我們將學習如何利用OSGi的API進行編程。所以,現在建立一個名叫“HelloWorldKiller”的Java文件,並且將以下代碼複製粘貼到裏面。
import org.osgi.framework.*;
public class HelloWorldKiller implements BundleActivator {
public void start(BundleContext context) {
System.out.println("HelloWorldKiller searching...");
Bundle[] bundles = context.getBundles();
for (int i = 0; i < bundles.length; i++) {
if ("HelloWorld".equals(bundles[i].getSymbolicName())) {
try {
System.out.println("Hello World found, " + "destroying!");
bundles[i].uninstall();
return;
} catch (BundleException e) {
System.err.println("Failed: " + e.getMessage());
}
}
}
System.out.println("Hello World bundle not found");
}
public void stop(BundleContext context) {
System.out.println("HelloWorldKiller shutting down");
}
}
然後我們同樣創建一個名叫HelloWorldKiller.MF的manifest文件。並將以下代碼粘貼到裏面。再次強調一下,在結尾處一定要留一個空行,否則程序無法運行。
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: DBLoginBundle Plug-in Bundle-SymbolicName: Login_DBLoginBundle Bundle-Version: 1.0.0 Bundle-Activator: HelloWorldKiller Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Import-Package: org.osgi.framework;version="1.3.0"
然後使用命令對這個Bundle進行打包。
> javac -classpath equinox.jar HelloWorldKiller.java
> jar -cfm HelloWorldKiller.jar HelloWorldKiller.mf HelloWorldKiller.class
打包完後,我們回到OSGi控制檯,使用命令“install file:HelloWorldKiller.jar”(“file”後是這個jar文件命)安裝這個Bundle。然後使用“ss”查看目前的Bundle狀態。大致情況如下:
id State Bundle 0 ACTIVE system.bundle_3.2.1.R32x_v20060919 1 ACTIVE HelloWorld_1.0.0 2 INSTALLED HelloWorldKiller_1.0.0
然後我們通過運行“start 2”這個命令來啓動Hello World Bundle。你將會在控制檯看到如下信息:
HelloWorldKiller searching... Hello World found, destroying! Goodbye EclipseZone Readers!
注意到了最後一行的輸出嗎?那是我們最初的Hello World Bundle。因爲在我們運行Hello World Killer之前,它是處於運行狀態的。當它被卸載的時候,先要被停止。因此,BundleActivator的stop方法會被執行。
然後我們再次輸入“ss”查看一下Bundle的運行狀態。HelloWorld的Bundle消失了。變成了下面的情況:
id State Bundle 0 ACTIVE system.bundle_3.2.1.R32x_v20060919 2 ACTIVE HelloWorldKiller_1.0.0
你可能通過上面的講述驚奇的發現那裏存在一個安全問題:我們可以通過任何一個Bundle卸載其他的Bundle。我們很幸運,OSGi有套全面的安全措施。這可以讓我們在與OSGi框架進行交互的時候,靈活的控制每一個細節。簡單的來說,你可以通過建立一個特殊的管理員Bundle來限制卸載其他Bundle的行爲。然而,獲得安全保障的工作最重要的是配置文件的定義。而我們這一系列的課程把焦點集中在代碼上。
以上就是這節課的全部內容。在下節課中,我們來看一下BundleContext接口並且看看我們能用它做什麼。比如,我們是否可以用installBundle方法來進行一個Bundle的安裝,或者查看運行中的Bundle的信息,並且打印出Bundle最近的修改時間和內容。爲了更好的進行下堂課的學習,請先查閱一下OSGi Release 4 API的幫助文檔。