OSGi规范
OSGi规范为网络设备定义了一个标准的,面相对组件的计算环境。给一个设备添加一个OSGi服务平台,可以从网络上的任何地方管理这个设备上的软件的生命周期,可以安装、更新和删除这些组件而无需中断设备的工作。软件组件是一些可以动态发现和使用其他组件的库或应用程序。这些组件可以从市场上购买也可以自己开发。OSGi 联盟已经为一些通用的功能如HTTP服务、配置服务、日志记录服务、安全服务、用户管理服务、XML服务等,开发了很多标准组件接口。可以从不同的软件供应商得到这些兼容的插入是组件的不同优化以后的实现。
软件组件架构在软件开发过程中越来越成为一个难题:需要开发和维护大量的配置信息。标准化的OSGi组件架构显著简化了这个配置过程。
OSGi规范包括了构建开发的可交付网络服务的各方面,实际上主要是规定了一组API,OSGi规范又包括了以下子规范:
1. Framework规范
OSGi Framework 规范是OSGi规范的核心组成部分,它提供了一个通用的、安全可管理的Java framework。通过这个Framework 可以支持一种叫做Bundles的服务应用的部署和扩展。这个Framewrok可以分成如下几层:
L0层:运行环境;L1层:模块;L2层:组件生命周期管理;L3:服务注册 L0运行环是Java运行环境的规范。Java2 的配置和Profiels , 比如J2SE、CDC、CLDC、MIDP, 都是有效的运行环境。OSGi也为低配置的平台定义了运行环境。
L1:模块层定义了class装载策略。OSGi Framework是一个强大的严格的class 装载模块。它基于Java但是添加了模块化的概念。在Java里,通常只有一个Classpath, 里面包括了所有的策略class和资源。OSGi模块层为各个模块添加了四月才class的概念和一种受约束的模块间共享的CLASS模型。
L2:软件生命管理周期可以添加Bundle并且可以动态安装、启动、停止、更新和卸载这些Bundle。Bundle依赖于模块层的CLASS载入但是添加了为运行时管理的API。生命周期管理层引入了应用程序通常不具有的动态性。有扩展的依赖机制用来保证环境的正确运行。
L3:这一层添加了一个服务注册表。服务注册为动态Bundles表提供了一个合作模型。Bundle可以通过传统的Class共享来合作,但是Class共享和动态安装和卸载代码不是很协调,服务注册表为Bundle之间共享对象提供了一个合理的模型。定义了一些事件来处理服务的安装和卸载。服务就是可以用来表示任何东西的Java对象。很多服务是服务器对象,比如HTTP server, 其他服务表示了以现实世界中的对象,比如打印机等。
安全机制是基于Java 和Java2的安全模型,这个语言的设计减少很多可能的安全漏洞,比如,病毒使用缓冲区溢出就不可能了。访问限制使得对其他程序员代码的可视性 受到了限制。OSGi通过私有的class扩从了这个模型。一个在标准Java环境里面无法达到的机制。Java2 安全模型提供了一种合理的模型来检查代码和资源的访问。OSGi 添加了完整的动态管理权限的机制。
OSGi兼容设备可以下载并安装OSGi bundle,也可当他们不再需要的时候删除。Bundle 安装后会注册一定数量的服务,并可以同一个Framework下的使用其它Bundles。
在一个动态扩展的OSGi环境中,Framework管理Bundle的安装和更新。同时也管理Bundles和服务之间的依赖关系。
在一个动态扩展的OSGi环境中,Framework管理Bundle的安装和更新。同时也管理Bundle 和服务之间的依赖关系。
Framework提供给Bundle开发者必须的资源来在Java平台上开发,为开发Bundles提供了代码动态加载的功能,也使得开发者开发、部署一个大规模的服务变得很容易。
其次,Framework为Java Bundle开发者提供了简明一致的编程模型。简化了开发部署的复杂性。这个编程模型允许开发者将自己的接口规范邦定到OSGi环境中的服务。服务的使用者可以使用这个接口,而其实现在运行时才决定。
一个一致的编程模型帮助开发者可以应付一些可估计的危机错误。Framework将会运行在不同的硬件环境上,但一致的接口确保软件可以运行在一致的服务接口上。
一个Bundle可能处于以下六个状态:
1)INSTALLED:安装完成,本地资源成功加载
2)RESOLVED:依赖关系满足,这个状态意味着这个Bundle要么已经准备好运行,要么是被停止了。
3)STARTING:Bundle正在被启动,BundleActivator的start()方法已经被调用但是还没有返回。
4)STOPPING:Bundle正在被停止,BundleActivator的stop()方法已经被调用但是还没有返回。
5)ACTIVE:Bundle 被成功启动并且在运行。
6)UNINSTALLED:bundle被卸载并且无法进入其他状态。
Bundle接口定义了getState()方法来返回Bundle的状态。
下面介绍Bundle的一些API:
安装Bundle
BundleContext 定义了以下两个方法来安装bundle:
1) installBundle (String):从String(一般是URL)定义的位置安装一个Bundle。
2)installBundle(String, InputStream):从一个输入流对象中安装一个Bundle。
每一个Bundle都是由一个Sting来唯一表识。如果一个已经安装的Bundle正在使用这个specificated location , installBundle()方法必须返回原来的Bundle对象,而不是安装一个新的Bundle。将要安装的Bundle必须是持久的并且安装时全自动的。
当安装一个Bundle时,Framework会去找出Bundle依赖的Nativecode 。如果不存在,bundle 不能被安装。
一旦一个Bundle安装成功,会创建一个Bundle对象。对Bundle的生命周期的操作都通过该对象完成。可以用来start , stop, update, ininstall 该Bundle。
解析Bundle
当Framework成功查找完Bundle的代码依赖关系,bundle的状态就变为RESOLVED。依赖关系包括:
Classpath 依赖关系,定义在manifest文件头的Bundle-Classpath处。
Package 依赖关系,定义在manifest文件头的Export-Package和Import-Package处。
启动Bundle
Bundle接口定义了start()方法来启动一个Bundle。 如果启动成功,bundle的状态变为ACTIVE并保持这个状态直到被停止。
Bundle为了被启动,首先必须先分析它的依赖关系。如果分析依赖关系失败,而去启动这个Bundle,start()方法会抛出一个BundleException异常。
如果bundle依赖关系分析成功,通过调用Bundle Activator对象来激活Bundle。BundleActivator接口定义了方法可供Framework 调用,来启动或者停止Bundle。
开发者可以在Bundle的manifest文件中定义一个Bundle-Activator manifest header, 来告诉OSGi environment 作为BundleActivator的类的文件全名。该类实现了BundleActivator接口。
对一个Bundle来说,提供一个Bundle Activator并不是必须的。但是只有通过这种方法才能得到Bundle的BundleContext对象。
当Framework成功查找完Bundle的代码依赖关系,bundle的状态就变为RESOLVED。依赖关系包括:
Classpath 依赖关系,定义在manifest文件头的Bundle-Classpath处。
Package 依赖关系,定义在manifest文件头的Export-Package和Import-Package处。
停止Bundle
Bundle interface 定义了stop()方法停止一个Bundle。该方法停止一个Bundle并将Bundlede状态改为RESOLVED。
BundleActivator 接口定义了stop(BundleContext)方法,由Framework调用来停止一个Bundle。该方法必须释放被激活的所有资源。所有的相关线成必须马上停止。线程代码不会再使用同Framework相关的对象。
更新Bundle
Bundle interface 定义了两个方法来update一个bundle:
1) update:更新一个bundle
2) update(InputStream) :这个方法用来从一个输入流对象中更新一个Bundle
更新过程支持从一个版本的bundle迁移到一个新版本的bundle。
Framwork 必须确保在任何时刻只有一个版本的bundle的class是可用的。如果被更新的bundle导出的任何的package被其他的bundle使用,那么那些package将不能被更新。他们的老版本将会一直保留,直到org.osgi.service.admin.PackageAdmin.resfeshPackages方法被调用或者Framework 重启。
卸载Bundle
Bundle 接口定义了uninstall()方法来从Framework中卸载一个Bundle。这个方法会让Framework通知其他的Bundles 说一个bundle已经被uninstalled, 并且将这个Bundle的状态设为UNINSTALLED。
2. 标准服务规范
在Framework的上方,OSGi联盟定义了很多服务。服务是由一个Java interface 来定义的。Bundle可以实现这个接口并且把服务注册到服务注册表中去。这个服务的客户可以从注册表中找到这个服务,并且对这个服务的出现和消失做出反应。
下面简单介绍一下OSGi Release3 的服务。每个服务只是被抽象地定义,具体由不同的厂商实现。
2.1 Framework服务
OSGi Framework提供了权限管理服务,包管理服务和最初加载系统服务。这些服务是Framewrok的一部分并且指导着Framework的操作,Framework服务包含如下:
1)Permission Admin Service:权限是指Bundle是否许可另外的Bundle的代码。当前的或者以后的Bundle的权限可以通过这个服务来操作。一旦被设定权限,马上就生效;
2)Package Admin Service:Bundle之间可以共享包内的class和资源,bundle的更新可能需要系统重新计算他们之间的依赖关系,这个服务提供了系统实际的包的共享状态信息并且可以更新共享的包。例如中断当前的依赖关系并重新计算依赖关系。当Bundle更新或反安装时判断是否有其他服务正在使用当前的bundle。
3)Start Lever Service:Start Level是指一些在其他Bundle起来之前必须运行或者初始化的一系列 bundle. Start Lever Service 设置当前的Start Lever, 将一个bundle 指派给startlevel 并且询问当前的设置。
2. 标准服务规范
在Framework的上方,OSGi联盟定义了很多服务。服务是由一个Java interface 来定义的。Bundle可以实现这个接口并且把服务注册到服务注册表中去。这个服务的客户可以从注册表中找到这个服务,并且对这个服务的出现和消失做出反应。
下面简单介绍一下OSGi Release3 的服务。每个服务只是被抽象地定义,具体由不同的厂商实现。
2.1 Framework服务
OSGi Framework提供了权限管理服务,包管理服务和最初加载系统服务。这些服务是Framewrok的一部分并且指导着Framework的操作,Framework服务包含如下:
1)Permission Admin Service:权限是指Bundle是否许可另外的Bundle的代码。当前的或者以后的Bundle的权限可以通过这个服务来操作。一旦被设定权限,马上就生效;
2)Package Admin Service:Bundle之间可以共享包内的class和资源,bundle的更新可能需要系统重新计算他们之间的依赖关系,这个服务提供了系统实际的包的共享状态信息并且可以更新共享的包。例如中断当前的依赖关系并重新计算依赖关系。当Bundle更新或反安装时判断是否有其他服务正在使用当前的bundle。
3)Start Lever Service:Start Level是指一些在其他Bundle起来之前必须运行或者初始化的一系列 bundle. Start Lever Service 设置当前的Start Lever, 将一个bundle 指派给startlevel 并且询问当前的设置。
(待续)