比窦娥还冤的CM

在之前的一篇blog中我曾经写到过CM对于application level的configuration的不适应,提到的主要是两点:
1、无法在外部统一的对Bundle中service所需要的属性进行管理;
      当时基于这个约束,只好在各自的bundle下编写一个管理当前bundle属性的服务,当外部需要管理此bundle的属性时,必须通过这个服务来管理,否则的话改变是不会起到效果的。
2、无法共享属性的配置。
      每个bundle都保存自己独立的一份属性配置,这就导致了当出现共享属性时,在管理端也不得不同时去重复的更新多个bundle。
昨天在调试产品的时候,又被CM搞的郁闷了一把,由于CM是根据BundleLocation和service.PID共同来绑定属性的,也就是说当BundleLocation改变了的情况下属性就无效了,而且也无法被重写,这对于实际的应用而言几乎是不可接受的,因为模块部署的路径、模块的名称改变这都是很正常的事,但根据CM这样的方式的话,也就意味着模块部署的路径、模块的名称都是不可改变的。
想想挺恼人的,就开始仔细的看Equinox的CM实现的代码,经过仔细的查看后,发现自己疏忽了一点,冤枉了CM,其实CM也是留了一个口以供上面这样的情况下的处理的,后来对照了下OSGi R4中CM规范的描述,确实如此,如果希望配置不要和bundleLocation绑定,那么可以在注册ManagedService接口实现的服务时将其server.bundleLocation设置为null,如下:
<component name="PortComponent">
       
<implementation class="com.terdon.spike.port.PortService"/>
       
<property name="service.pid" value="com.terdon.port"/>
       
<property name="service.bundleLocation" value="null"/>
       
<service>
               
<provide interface="org.osgi.service.cm.ManagedService"/>
       
</service>
</component>
然后就可以在其他的管理属性的服务中调用ConfigurationAdmin来实现对这个service的属性的管理:
Configuration configuration=admin.getConfiguration("com.terdon.port", null);
根据这样的分析,也就是说我以前所说的第一点的情况是冤枉了CM,现在开始给它平反,:)
摘一下OSGi R4 CM规范中对于这种情况的描述:
"Bundles with the required permission can create Configuration objects that
are not bound. In other words, they have their location set to null. This can
be useful for pre-configuring bundles before they are installed without having
to know their actual locations.
In this scenario, the Configuration object must become bound to the first
bundle that registers a Managed Service (or Managed Service Factory) with
the right PID.
A bundle could still possibly obtain another bundle’s configuration by registering
a Managed Service with the right PID before the victim bundle does
so. This situation can be regarded as a denial-of-service attack, because the
victim bundle would never receive its configuration information. Such an
attack can be avoided by always binding Configuration objects to the right
locations. It can also be detected by the Configuration Admin service when
the victim bundle registers the correct PID and two equal PIDs are then registered.
This violation of this specification should be logged."
从上面这段描述中,可以看出,CM之所以这么设计主要还是从安全性的角度考虑的。
但对于第二点,目前看来确实是如此,属性无法共享,因为pid必须是唯一的,我已经发了邮件给equinox maillist,看看是不是有人会有办法,:)

posted on 2006-11-22 11:59 BlueDavy 阅读(1940) 评论(5)  编辑  收藏 所属分类: OSGi、SOA、SCA

评论

# re: 比窦娥还冤的CM 2006-11-22 16:30 huang[匿名]

你好,我在看你的《osgi实战》中的实例代码,有个小问题请教一下,就是那个Plug-in Dependencies中是的jar包是怎么设置的,是不是自动根据metafest.mf获取的。如果一个bundle依赖一个jar包,可以将它通过配置在buildpath设置中,也可以将jar包转为一个bundle在METAFEST.MF中配置,这两种方法是不是通用的?谢谢

另外关于Required Plug-in和Imported Package的问题。在《实战》一书中,同样是关联类,为什么LDAP关联user下的接口时用Imported Package,而WebBundle关联HttpServlet类时使用Required Plug-in呢。是不是二者是通用的,前者是import所有的类,而后者是通过import部分类,其实也是required了相应的bundle的?  回复  更多评论   

# re: 比窦娥还冤的CM 2006-11-22 22:21 BlueDavy

@huang[匿名]
不好意思,你的第一段话的问题我看的不是非常的明白,只能按我的理解说说了,如果一个Bundle依赖jar包,做法基本上和普通的java project没什么区别,就是都是以jar包形式放入lib目录,然后在buildpath上加上,只是在Bundle的情况下还需要在MANIFEST.MF的Runtime/Classpath上也加上这个jar包,在Eclipse中如果是先在MANIFEST.MF的Runtime/Classpath加上jar包的话,那么可以自动同步build path。

至于第二个问题,require通常用于可以获取该bundle中所有的export的包,同时还有个作用就是可以获取该bundle的资源文件,因为webbundle关联httpservlet类的那个bundle中只有一些servlet相关的api的类,所以我就用了require的方式,两者还是有区别的,尽量不使用require,而使用imported。  回复  更多评论   

# re: 比窦娥还冤的CM 2006-11-22 23:27 huang[匿名]

谢谢BlueDavy的回答,我明白了 thx  回复  更多评论   

# re: 比窦娥还冤的CM 2007-01-27 00:42 shakebaby

CM这部分我还不够理解,不过之前看规范时为PID和Location的确感到奇怪。  回复  更多评论   

# re: 比窦娥还冤的CM 2007-01-27 15:52 BlueDavy

@shakebaby
用用就理解了,:),还是个不错的东西,我现在产品中的配置都是用它了。  回复  更多评论   


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


网站导航:
 

公告

 









feedsky
抓虾
google reader
鲜果

导航

<2006年11月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

统计

随笔分类

随笔档案

文章档案

Blogger's

搜索

最新评论

阅读排行榜

评论排行榜