欢迎回来EclipseZone OSGi指导系列。
上一次,我们看了一个简单的Hello World的Bundle在开始和结束的时候输出一段信息。它通过实现BundleActivator接口和start和stop方法。现在再看看代码,在特定方法start和stop方法的标记中,你将注意到我们传递了一个参数BundleContext。在指导的这个部分中,我们将研究下BundleContext并且我们能用它来做什么。
BundleContext是一个OSGi框架传递给我们的Bundle的一个魔力入场券。当代码需要在任何时候与框架交互时,你将用到BundleContext。事实上这是用OSGi API交互的唯一方法,并且框架在Bundle启动的时候将这些入场券发通过它们的BundleActivator发给每一个Bundle。
如果你从上次课程一直有个Equinox在运行,你不需要重启它。如果它没有运行,那么记住启动它的命令:
1 | > java -jar equinox.jar –console |
在提示符后输入ss并且你将看到上次课程的Hello World Bundle一直处于installed。甚至在你关闭并重启Equinox之后,因为OSGi框架还残留着运行之间它的状态。
对于这次练习,我们将写一个Bundle搜索出并卸载Hello World。我们可以从控制台简单的使用usinstall命令,但是我们想见识下它如何使用OSGi API程序化的完成。所以,我们创建一个新的名为HelloWorldKiller.jar文件并复制如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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"); } } |
现在创建manifest。再说下,记住结尾的空行是非常重要的。复制以下内容到HelloWorldKiller.mf:
1 2 3 4 5 6 7 | Manifest-Version: 1.0 Bundle-Name: HelloWorldKiller Bundle-Activator: HelloWorldKiller Bundle-SymbolicName: HelloWorldKiller Bundle-Version: 1.0.0 Import-Package: org.osgi.framework
|
现在,编译并建立Jar:
1 2 | > javac -classpath equinox.jar HelloWorldKiller.java > jar -cfm HelloWorldKiller.jar HelloWorldKiller.mf HelloWorldKiller.class |
回到OSGi控制台,使用install file:HelloWorldKiller.jar安装新的Bundle,然后输入ss。状态列表现在看起来会像这样:
1 2 3 4 | 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 Killer。你将看到如下输出:
1 2 3 | HelloWorldKiller searching... Hello World found, destroying! Goodbye EclipseZone Readers! |
注意,最后一行输出来自于我们原始的Hello World Bundle。因为我们运行Killer之前它是active状态,它要变成uninstalled前变为stoped,由于它的BundleActivator的stop方法运行了。
再看下ss的输出结果,Hello World消失了。
1 2 3 | id State Bundle 0 ACTIVE system.bundle_3.2.1.R32x_v20060919 2 ACTIVE HelloWorldKiller_1.0.0 |
你可能惊叹这是一个安全问题。出现了任何一个Bundle可以卸载任何其它的Bundle!幸运的是OSGi有一个全面的安全层给予所有框架交互的细粒度控制,例如你可能限制卸载一个指定的"管理"Bundle的权限。然而,获得安全工作大部分是一个配置问题,并且在这个系列中,我们将聚焦于这些代码。
这就是这部分的内容了。在下次前,为什么不看看BundleContext接口和看看你还能使用它来做些什么?例如,你可以试着使用installBundle方法来程序化的装载一个新的Bundle。或者你可以获得所有当前安装的Bundle的列表并输出它们最后一次修改的日期和时间。为了帮助你入门,查看Javadocs for the OSGi Release 4 APIs。
参考:
没有评论:
发表评论