Felix动态化的试验

本文内容同样摘自《OSGi原理与最佳实践》,在之前的blog中也摘选了部分内容分析了Equinox的动态化,在这里再试验下Felix的动态化,关注点为:“即插即用”、“热部署”、“即删即无”,看下Felix在这几方面的表现和Equinox有什么不同。

在动态化方面,最为关心的是Felix在“即插即用”、“热部署”以及“即删即无”三点上的表现,这三点涉及到的主要是引用对象的迁移以及对象状态的保留,而对于OSGi的应用,引用对象的迁移涉及到的为package依赖以及OSGi服务依赖的迁移,在对象状态的保留上,OSGi不提供支持,为了更方便的观察Felix在动态化的表现,在程序中直接启动Felix,通过这样的方式获取到BundleContext,进而调用BundleOSGi服务的方法来检测package依赖、OSGi服务依赖在“即插即用” 、“热部署”以及“即删即无”这三种情况下的变化情况,在程序中启动Felix的代码片段如下:

FrameworkFactory factory=new FrameworkFactory();

    Properties startProps=new Properties();

    startProps.put("felix.auto.start.1", "file:bundle/org.apache.felix.scr-1.0.8.jar file:bundle/org.apache.felix.shell-1.2.0.jar file:bundle/org.apache.felix.shell.tui-1.2.0.jar file:bundle/org.apache.felix.bundlerepository-1.4.0.jar");

    List list = new ArrayList();

    list.add(new AutoActivator(startProps));

    startProps.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, list);

    startProps.put("felix.log.level", "1");

    startProps.put("osgi.shell.telnet", "on");

    Framework framework=factory.newFramework(startProps);

    framework.start();

    context=framework.getBundleContext();

l  即插即用

即插即用是硬件体系中宣传的最多的一项,例如USB硬件等,对于OSGi的应用,此时期待的是安装上新的Bundle后,此新Bundle的功能即可正常使用。

package依赖和服务依赖两个角度来看,假设A Bundle对外提供了HotDeployDemoService实现,此实现依赖了B Bundle对外exportorg.osgichina.domainpackage以及D Bundle对外exportorg.osgichina.hotdeploy.servicepackage,实现还需要调用DBService,此OSGi ServiceC Bundle对外提供,C Bundle也依赖于D Bundle exportDBService的接口package,同时此实现采用了一个计数器来计数执行的次数,代码片段如下:

A Bundle

public class DemoComponent implements DemoService {

 

    private AtomicInteger count=new AtomicInteger(0);

   

    private DBService dbservice;

   

    public void setDBService(DBService dbservice){

       this.dbservice=dbservice;

    }

   

    public void unsetDBService(DBService dbservice){

       if(this.dbservice==dbservice){

           this.dbservice=null;

       }

    }

   

    /* (non-Javadoc)

     * @see org.osgichina.hotdeploy.demo.service.DemoService#execute()

     */

    @Override

    public void execute() {

       System.out.println("execute times:"+(count.incrementAndGet()));

       User user=new User();

       dbservice.execute(user.getName());

    }

 

}

B Bundle

public class User {

 

    public String getName(){

       return "bluedavy";

    }

   

}

C Bundle

public class DBComponent implements DBService {

 

    @Override

    public void execute(String username) {

       System.out.println("execute DBComponent,username is:"+username);

    }

 

}

通过程序在外部启动Felix,每5秒钟执行下DemoServiceexecute方法,启动完毕后,首先安装上A Bundle,此时由于A Bundle缺少了所依赖的package以及OSGi服务,其需要对外提供的OSGi服务必然也无法激活,因此console输出了以下信息:

未找到需要调用的服务

安装并启动B BundleDBundle,尝试启动A BundleConsole仍然输出:

未找到需要调用的服务

继续安装并启动C Bundle,尝试启动A BundleConsole输出:

execute times:1

execute DBComponent,username is:bluedavy

从上可见,在Felix中要达到即插即用的效果还是非常容易的,只要安装并启动了所依赖的packageBBundleDBundle)和OSGi服务所在的BundleCBundle)后,再行启动依赖这些packageOSGi 服务的BundleABundle),那么新安装的Bundle的功能就可被使用,效果也称得上是即插即用了。

l  热部署

热部署期待的效果是直接覆盖需要更新的jar,所有新的请求都会自动执行到新的代码中,且保留更新的对象的状态。

仍然采用即插即用中的例子,分别来看看当B BundleC Bundle更新时A Bundle服务执行的状况,将B BundlegetName修改为return  “osgi”;,覆盖B Bundle,执行update后,观察console的输出:

execute times:23

execute DBComponent,username is:bluedavy

从此可见,updateB Bundle的修改并没生效,尝试执行下refresh后,继续观察console的输出:

execute times:1

execute DBComponent,username is:osgi

可以看到,此时B Bundle的修改已生效,但伴随的是execute times这个对象状态的重置。

继续修改C Bundle,将C Bundle打印的信息改为,execute new DBComponent,修改完毕后覆盖C Bundle,执行update后,观察console的输出:

execute times:1

execute new DBComponent,username is:osgi

可见C Bundle的修改立刻生效了,但同样伴随着的是execute times这个对象状态的重置。

按照如上的试验,在使用Felix的情况下,如要更新其他Bundle依赖的packageBundle,需要采用的步骤为:覆盖bundle文件àupdate bundleàrefresh,;如要更新其他Bundle需要调用的OSGi服务的Bundle,需要采用的步骤为:覆盖bundle文件àupdate bundle;但两者伴随着的都是更新的Bundle以及依赖(递归)了其的Bundle中的对象状态的丢失,可见,要想基于Felix就直接得到热部署的效果还是做不到的,需要在Felix的基础上自行做一定的扩展。

l  即删即无

即删即无期望的效果是在停止Bundle后,其所对外exportpackage以及OSGi Service都不再可用,仍然采用即插即用中的例子进行测试。

首先来看看停止B Bundle后,观察console的输出:

execute times:168

execute new DBComponent,username is:osgi

可见,这么做并不会影响A Bundle使用B Bundle exportpackage,那么尝试使用uninstall B Bundle,这下行了吧,满心期待的观察console的输出:

execute times:185

execute new DBComponent,username is:osgi

居然仍然可以使用,看来只能再尝试下refresh了,继续观察console的输出:

未找到需要调用的服务

恩,这才是期待的效果,说明此方法可行。

继续安装上B Bundle,来看下停止C Bundle后,console的输出:

未找到需要调用的服务

恩,正如期待的效果,说明此方法可行。

由上可以看出,在Felix中要达到即删即无的效果,对于有对外export packageBundle,在uninstall后必须再执行refresh动作;而对于有对外提供OSGi服务的Bundle,则只需执行stop动作即可。

posted on 2009-05-25 22:58 BlueDavy 阅读(5123) 评论(4)  编辑  收藏 所属分类: OSGi、SOA、SCA

评论

# re: Felix动态化的试验 2009-05-28 12:59 mellon

Davy,为何在china.osgiusers.org中,没有看到你2007年后的文档、文章什么的?貌似该站已经停滞了,为什么呢?  回复  更多评论   

# re: Felix动态化的试验 2009-05-28 23:32 BlueDavy

@mellon
...一直没抽出时间去维护下那个站,:)  回复  更多评论   

# re: Felix动态化的试验 2009-08-28 17:08 常高伟

@BlueDavy
如果可以的话,我愿意尽绵薄之力。
如果OSGI中国 有开源项目的话,我也希望可以参加一下。
期待china.osgiusers.org能够在林前辈的带领下活跃起来!
  回复  更多评论   

# re: Felix动态化的试验 2009-08-31 09:26 BlueDavy

@常高伟
恩,非常感谢。  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 

公告

 









feedsky
抓虾
google reader
鲜果

导航

<2009年5月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

统计

随笔分类

随笔档案

文章档案

Blogger's

搜索

最新评论

阅读排行榜

评论排行榜