星期三, 六月 25, 2008

[JAVA]OSGi入门:与框架交互[译]

欢迎回来EclipseZone OSGi指导系列。 

上一次,我们看了一个简单的Hello WorldBundle在开始和结束的时候输出一段信息。它通过实现BundleActivator接口和startstop方法。现在再看看代码,在特定方法startstop方法的标记中,你将注意到我们传递了一个参数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,由于它的BundleActivatorstop方法运行了。 

再看下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 


参考

没有评论: