- 浏览: 510079 次
文章分类
最新评论
OSGi规范中文版(第5版 core R5.0.0)-第3章模块层(Module Layer)2
3.3 依赖
OSGi依赖处理基于非常普通的模型来描述依赖关系,这个模型有一些小的原始概念:
- 运行环境-framework安装资源的容器
- Resource-抽象的artifact需要以某种方式安装后,来提供预期的功能。Bundle是一个资源模型,例如显示器或者USB密钥都是resource。
- Namespace –定义运行环境在给定的命名空间中匹配requirement和capability
- Capability –描述在运行环境中install的resource特性和功能,capability包含属性和指令。
- Requirement –声明capability在运行环境中的可用性。Requirement包含属性和指令。filter指令包含在 同一个namespace中进行过滤的属性断言。 在图3.2种描述了这几个实体之间的关系:图 3.2 Core Requirement/Capability模型 通常一个Resource会依赖其他Resource或者被其他Resource依赖。
Dependency类型变化很大,如一个Bundle能够从别的Bundle(Import-Package)中要求package,或者一个Fragment需要主Bundle(Fragment-Host),或者Bundle要求接入高分辨率显示器。OSGi Core规范用专用的header描述不同类型的可能依赖,以及每一种情况下的优化,然而,这个模型要求依赖的各种类型通过一个规范的过程处理,并且有效的限制各方不参与这个过程。因此,规范中提供了一个基于namespace的通用依赖模型,namespace是dependency的一个类型。例如,osgi.wiring.package Namespace通过指定数量的属性和指令定义了Import-Package和Export-Package语义。另外为匹配和指令使用属性提供了关于Namespace的语义信息,例如在osgi.wiring.host Namespace (Fragments)下,对应capability属性有:
- osgi.wiring.host – (String) host name.
- bundle-version – (Version) host version.
- * –允许其他任意属性 OSGi Framework Namespace定义的类,具体可参考第8章Framework Namespace规范
Namespace的目的是创建一组属性/指令基础语言,这个基础语言描述了通用的dependency与具体dependency类型无关性,另外Namespace的数量在OSGi联盟和其他规范中也有所定义,并且OSGi namespace开头保留osgi.前缀,例如,osgi.ee这个namespace定义了指定可执行环境下的capability。Namespace也能被其他组织和个人定义,故为了减少命名空间冲突,使用package和bundle symbolic name时建议使用反向域名规则。OSGi组织推荐注册的Namespace,可参考[16] OSGi Header Namespace Registry to prevent clashes。
指定一个Namespace,可以声明为Namespace的capability。Capability也提供了定义在namespace下的属性和指令。例如,在osgi.wiring 包Namespace中可以转化Export-Package头信息到capability。
指定一个capability,可以声明为requirement。如果requirement是需要满足的一些条件的话,Requirement则使用filter来作为匹配capability的属性,Requirement通常关联Namespace。Requirement使用的filter条件指令匹配capability,filter语法标准参考3.2.7 Filter语法。Requirement有2种属性(mandatory或optional)来描述指令集使用。Requirement可以有一个或者多个基数,表明它至少需要一个或者更多的Capability。
当Resource强制要求由一个或者多个Capability满足时,Resource则声明requirement来提供其预期的功能,Capability通常由其他Resource提供。Resource认为所有的mandatory requirement都是要解决的,而且必须是通过Resource的Capability所提供的功能描述来满足requirement。Capability只有在Resource被resolve时才需要满足requirement要求。
匹配requirement capability的处理过程被称为resolving。在这个处理过程中,resolver必须创建wire(wire是指和requirement/Capability的一种连接关系)。Wire和requirement/Capability存在引用关联Resource。在某些情况下,requirement/ capability可以在一个Resource中声明,但是会有来自其他Resource的wire。然而,当一个Resource有wire,那么wire具有相应provider或者requirer声明的不同Resource。声明Resource用于不同的provider或者requirer的过程称为hosting。这种分割形成Fragment,Fragment包含一些主要的requirement/Capability以及关联Fragment的其他部分。
只有有效的requirement必须被wire,而且每个requirement的目的是为了保持一定的系统状态。例如,OSGi Framework只根据requirement的有效指令设置去resolve。
一旦一组Resource在运行环境中被resolve了,那么OSGi Framework会给Bundle的每个Resource创建Wiring来保持resolve状态,这个状态无论如何都会包含wire信息。
Wire在requirement和capability之间必须根据他们之间的Namespace语义创建。Wire在resolve操作中产生,并运行在指定的Namespace中使用。例如,osgi.wiring.*这个Namespace将控制class加载(具体参考第7章Bundle Wiring API 标准)。而且也能通过Namespace描述其他服务,例如,wire能指定Dependency注入的source和target。
通常模型的接口定义在org.osgi.resource。在Bundle Wiring API规范中描述了wiring API基于这个普通的package,一般API会兼容其他规范(OSGi Core framework’s Capability /Requirement模型)。
3.3.1 Bundle
所有的Bundle依赖一个或者多个外部实体,这种关系通过requirement和Capability表达。
当Bundle第一次被resolve时,会假设所有的依赖关系是可满足的。Manifest的Require-Capability和Provide-Capability头信息将requirement和Capability都声明在Namespace中。于是,一些在OSGi规范中的manifest头在Capability中指定了其他OSGi manifest头的真实requirement。例如,一条Import-Package clause在capability中指明一条require Export-Package
clause。Import-Package clause的属性与Export-Package clause属性相对应。故规范中也为OSGi manifest header预留了一些Namespace:osgi.wiring.bundle, osgi.wiring.package, osgi.wiring.host。这些Namespace会影响resolver和定义类加载处理过程,例如,Require-Bundle clause是一个requirement时,将会确保依赖Bundle export过的package在对应依赖的类加载中是有效的。
OSGi resolve过程在3.8解析过程中描述。图3.3描述了Requirement/Capability模型。
图3.3
3.3.2 使用示例
Bundle在window中指定java规范版本以及require一个显示器像素为1000x1000,并且依赖于IP-number-to-location table。
这些依赖关系在运行环境中使用如下的规则描述(其他Bundle也可以这样使用):
Require-Capability:
com.microsoft; filter:="(&(api=win32)(version=7))",
com.acme.display; filter:="(&(width>=1000)(height>=1000))",
com.acme.ip2loc
每一条clause存在namespace,例如com.microsoft。namespace定义了语义属性以及可选的规则。
环境部署时设置启动属性来启动framework:
org.osgi.framework.system.capabilities.extra = «
com.acme.display; width:Long=1920; height:Long=1080; interlace=p, «
com.microsoft; edition=home; version:Version=7; api=win32
com.acme.ip2loc
Framework已经有需要的display requirement,但是ip2loc table requirement还没有的时候,部署环境将会install ip2loc table Bundle,这个Bundle的header如下:
Provide-Capability: com.acme.ip2loc; version:Version=1.2
在install和resolve这个Bundle之后,framework就能将最初的Bundle resolve了。
3.3.3 Bundle Capability
Bundle的capability定义在Provide-Capability头中。这个头的语法如下:
Provide-Capability ::= capability ( ',' capability )*
capability ::= name-space
( ’;’ directive | typed-attr )*
name-space ::= symbolic-name
typed-attr ::= extended ( ’:’ type ) ’=’ argument
type ::= scalar | list
scalar ::= ’String’ | ’Version’ | ’Long’
| ’Double’
list ::= ’List<’ scalar ’>’
Header具有以下指令架构:
- effective – (resolve)指定时间内capability是有效的,而且可以resolve(default)或者其他名字。OSGi framework resolver只考虑没有effective的指令或者effective:=resolve。Capabilty可以通过一个外部代理为effective指令使用其他值。
- uses –uses指令列出需要使用的package名称。此信息用于uses约束。具体参考3.7.5Package约束。 而且Namespace能定义额外的指令和属性。
3.3.4 Bundle Capability属性
属性是可以定义类型的,类型的内容也非常重要,因为这定义了如何比较属性。在不提供比较语义版本的时候通过字符串比较版本,同样字典序的数值排序也是不同的。
类型描述在属性名和等号(’=’ \u003D)之间,用冒号(’:’ \u003A)分割;例如Long类型:
attr:Long=24
如果没有指定类型,那么会认为是String类型。
解析规则通过对应的String类型构造函数创建一个实例,并且放在capability的map中。数值类型必须去除value前后的空白符号,类型周围的其他空白符号也会被忽略,允许跳过manifest的空白符号规则检测的示例如下:
attr:Long= 23 , // ok
attr:Version=" 23 ", // error
attr:Long=" 23 ", // ok, because numeric
多个属性值可以通过List<>描述,List<>操作定义了一个泛型来重复参数值,参数值之间用逗号(’,’\u002C)分隔,相应的参数列表解析必须遵守以下规则:
- 逗号附近的空白符号必须被去除
- 逗号或者斜杠(’\’\u005C)是值的一部分,需要对他们使用斜杠进行转义。
- 整个参数必须用双引号包含起来,因为逗号在manifest语法中是一个重要标志 version属性require Version类型的比较示例: version:Version=1.23 例如, Provide-Capability: « com.acme.dictionary; from:String=nl; to=de; version:Version=3.4, « com.acme.dictionary; from:String=de; to=nl; version:Version=4.1, « com.acme.ip2location;country:List="nl,be,fr,uk";version:Version=1.3,« com.acme.seps; tokens:List="\,,;,\\""
3.3.5 System Bundle Capability
Capability通过下面的运行属性提供system Bundle:
org.osgi.framework.system.capabilities
org.osgi.framework.system.capabilities.extra
这些系统属性的格式和Provide-Capability一样,framework必须解析这些属性,如果属性是system Bundle提供的,framework还需要在resolve过程中使用。
这2个属性以便framework通过org.osgi.framework.system.capabilities
属性指定framework默认的Capability,而通过org.osgi.framework.system.capabilities.extra system属性来具体部署Capability。Framework经常从他们的环境中演绎出许多Capability。
下面是system Bundle定义的capability header:
map.put("org.osgi.framework.system.capabilities.extra",
"com.acme.screen; width:Long=640; height:Long=480; card=GeForce");
3.3.6 Bundle Requirements
Bundle的Require-Capability header语法如下:
Require-Capability ::= requirement ( ',' requirement )*
requirement ::= name-space ( ';' parameter )*
Requirement的属性在Require-Capability中设置,提供这个属性的目的为requirement提供更详细的信息。
Import-Package, Require-Bundle, Fragment-Host这些头的属性映射在其对应的命名空间中的过滤指令里。
Require-Capability的指令架构如下:
- effective – (resolve) 指定时间内capability是有效的,而且可以resolve(default)或者其他名字。OSGi framework resolver只考虑没有effective的指令或者effective:=resolve。Capabilty可以通过一个外部代理为effective指令使用其他值。
- resolution – (mandatory|optional) mandatory表示requirement不满足时,是否还强制Bundle resolve;option表示如果requirement不满足时,是否还允许bundle resolve。当requirement都不能被resolve时则没有wiring,而且bundle尝试使用的package不能resolve时将会抛出ClassNotFoundException,如果设置了optional则可以不resolve。默认值是mandatory。
- filter – (Filter) filter表达式指过滤出属于指定namespace的Capability。对capability的filter匹配是一次只匹配一个capability。假设filter= (&(a=1)(b=2)),那么正确需要匹配2个capability,这时候如果filter是optional的,那么filter指令也会竟然去匹配。
- cardinality – (single|multiple)表示requirement可以被wire(指定引用集)一次或者多次,默认是single。 Additional directives are ignored during resolving. Attributes on the requirement clause are also ignored. 在resolve过程中额外的指令会被忽略,requirement clause属性也会被忽略。
3.4 运行环境
Java环境提供的所有package在java.这个namespace中,这个namespace没有很好的定义不同运行环境,例如,Java SE 5不同于Java SE 7,Android环境与Java SE环境有非常大的差异,然而,Java SE 6向后兼容Java SE 5, Java SE 1.4, Java SE 1.3 and Java SE 1.2,也就是说Java SE 1.3环境下的程序也能够运行在Java SE 5环境。
由于这些差异和向后兼容不能在运行时获取版本,例如,[21] Google Android是Java SE 5环境的变化,以及[22] Google App Engine and [23] Google Web Toolkit.在java.namespace中有不同的package、type和method。
Bundle不能import java.的package,因此环境中不能在Import-Package头中指定这些的依赖。OSGi运行环境定义了framework如何在变化的执行环境中通知Bundle,运行环境的主要定义在java.namespace中,运行环境也包含其他package的namespace。
运行环境需要一些合适的名字识别变化:
- Bundle resolve之前需要知道Framework提供的运行环境
- 提供Framework的运行环境信息
3.4.1 Bundle-RequiredExecutionEnvironment
Bundle-RequiredExecutionEnvironment manifest header提供了osgi.ee capability功能,而且在多个运行环境下执行的Bundle必须约束在manifest文件,而且多个运行环境用多个逗号分隔表示:
例如:
Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0, «
OSGi/Minimum-1.1
如果Bundle包含这个header,那么Bundle只能使用在运行环境中签名过的方法。必须列出所有(已知)的运行环境支持Bundle运行。
如果framework运行在vm上,vm需要实现一种执行环境,而且Bundle只能resolve。Framework需要能够识别当前VM实现了多个运行环境,例如,Java 6向后兼容Java 5,但是Bundle需要在Java 6运行环境上那就必须在Java 6 VM上resolve。
Bundle-RequiredExecutionEnvironment头不能阻止Bundle的安装。org.osgi.framework.executionenvironment运行属性定义了当前运行环境名称(多个环境名称用逗号分隔)。如果没有设置,framework必须提供一个适当的值。这个属性不赞成使用,这个属性功能代替了org.osgi.framework.system.capabilities[.extra]。
例如:
org.osgi.framework.executionenvironment =JavaSE-1.5, J2SE-1.4, JavaSE-1.4, JavaSE-1.3, OSGi/Minimum-1.1
Framework必须使用Wiring API转换Bundle-RequiredExecutionEnvironment头到osgi.ee namespace中,具体可参考第7章Bundle Wiring API 规范。
由于header在运行环境中可以使用不透明的名字,而且在运行环境中没有保证的算法映射ee-name到Require-Capability头中,于是,建议名字使用目前流行的运行环境命名,这样也可以用来创建的一个header结构,ee-name里的bree语法结构如下:
bree’ ::= n1 ( ’-’ v )? ( ’/’ n2 ( ’-’ v )? )?
示例:
CDC-1.0/Foundation-1.0
OSGi/Minimum-1.2
J2SE-1.4
JavaSE-1.4
每一个Btree元素的匹配模式可以被转换为osgi.ee Require-Capability filter。第一个变量n1必须被替换成JaveSE(Require-Capability需要Java Standard Edition名称时),filter指令由n1,v,n2构成,如果n2或者v未定义,那么扩展的指令也是未定义的:
bree-filter ::= '(&(osgi.ee=' n1 ('/' n2 )? ') ( '(version=' v ')' )? ')'
如果bree指定部分不能被解析,那么必须如下样子:
filter ::= '(osgi.ee=' ')'
一些例子:
Bundle-RequiredExecutionEnvironment例子:
Bundle-RequiredExecutionEnvironment:
CDC-1.0/Foundation-1.0,
OSGi/Minimum-1.2,
J2SE-1.4,
JavaSE-1.6,
AA/BB-1.7,
V1-1.5/V2-1.6,
MyEE-badVersion
上述的Bundle-RequiredExecutionEnvironment例子必须转为如下的Require-Capability:
Require-Capability:osgi.ee; filter:="(|
(&(osgi.ee=CDC/Foundation)(version=1.0))
(&(osgi.ee=OSGi/Minimum)(version=1.2))
(&(osgi.ee=JavaSE)(version=1.4))
(&(osgi.ee=JavaSE)(version=1.6))
(&(osgi.ee=AA/BB)(version=1.7))
(osgi.ee=V1-1.5/V2-1.6)
(osgi.ee=MyEE-badVersion)
)"
每一个org.osgi.resource.Resource代表Bundle-RequiredExecutionEnvironment的Bundle,转换后的osgi.ee requirement可以通过getRequirements(String)获得。
相关推荐
OSGi 中文版 中文 OSGi中文OSGi 中文版 中文 OSGi中文OSGi 中文版 中文 OSGi中文OSGi 中文版 中文 OSGi中文OSGi 中文版 中文 OSGi中文OSGi 中文版 中文 OSGi中文OSGi 中文版 中文 OSGi中文OSGi 中文版 中文 OSGi中文
很简单的介绍OSGI的前景开发和详细的介绍了OSGI的结构,是一本学习的很好的书,大家可以看看
Spring OSGi规范 中文版 Spring框架是一个领先的full-stack Java/JEE应用框架。它提供一个轻量级的容器,依赖注入、aop、可插接的服务抽取,这些使得非侵入式的编程模型成为可能。OSGi提供了一个动态应用程序的执行...
包含翻译后的API文档:osgi-resource-locator-1.0.1-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.glassfish.hk2:osgi-resource-locator:1.0.1; 标签:glassfish、osgi、resource、locator、hk2、jar包、...
osgi framework 5.0说明文档 osgi插件式框架,在java中得到成功应用,并应用于eclipse框架
osgi最新规范第四版, eclipse插件结构就是基于此规范编写的
OSGI原理与最佳实践的完整版,共12章 第1 章OSGi 简介 第2 章OSGi 框架简介 第3 章基于Spring-DM 实现Petstore 第4 章基于Apache CXF 实现分布式Petstore 第5 章构建OSGI Bundle Repositor'y 第6 章OSGi 规范解读 ...
OSGi R4规范OSGi R4规范OSGi R4规范OSGi R4规范OSGi R4规范OSGi R4规范OSGi R4规范OSGi R4规范OSGi R4规范OSGi R4规范
基于java的开发源码-OSGi 分布式通讯组件 R-OSGi.zip 基于java的开发源码-OSGi 分布式通讯组件 R-OSGi.zip 基于java的开发源码-OSGi 分布式通讯组件 R-OSGi.zip 基于java的开发源码-OSGi 分布式通讯组件 R-OSGi.zip ...
osgi核心规范文档,osgi服务文档,osgi-最佳原理与实践(王昊编著,共79页)
标签:glassfish、osgi、resource、locator、hk2、jar包、java、API文档、中英对照版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持...
osgi.core-5.0.0,osgi.enterprise-5.0.0
spring-osgi-1.2.0-rc1-with-dependencies.zip
OSGI越来越受到关注,OSGI R4规范,学习OSGI的首选,并且是中文版
osgi最新jar包org.osgi.core-4.2.0
OSGi原理与最佳实践基于作者多年使用0SGi的经验而编写,涵盖了0SGi从/kfqN深入的知识体系,从OSGi的简介开始,介绍OSGi的作用及基本概念;其后进入OSGi实战,...第11章 先睹为快:OSGi R4.2草稿版 第12章 OSGi展望
rpm安装包,rpm -i example.rpm
本文通过介绍传统 OSGi 应用程序及 R-OSGi 的实现方式入手,阐述了 R-OSGi 对于 OSGi 规范的实现方式。然后通过一个简单的功能实现由浅入深地讲述传统 OSGi 和 R-OSGi 上的两种不同实现,让您对实际操作加深印象。...
spring-osgi-1.2.1-with-dependencies.zip spring-osgi-1.2.1-with-dependencies.zip spring-osgi-1.2.1-with-dependencies.zip
这个版本是OSGi服务平台规范的第四个版本,由OSGi成员公司的代表共同开发完成,这个版本将原来的API扩展到了新的领域,修正了部分现有的API,以前的应用可以直接运行在新版本的框架中。