3.1 介绍
Java platform只是提供了打包、部署、Java基础应用和组件验证的最小化支持。因此,许多java基础工程经常借助于专用的类加载器来创建用户模块层,用户实现打包、部署、应用和组件验证,如JBoss、NetBeans。OSGi Framework提供了一个通用标准的java模块化解决方案。
3.2 Bundle
Framework定义了模块化单元,这个模块化单元称为Bundle。一个Bundle由Java类和其他资源文件组成,并且可以为终端用户功能。Bundle通过良好的定义,Bundle之间可以通过导入(import)和导出(export)来共享Java package。在OSGi Framework中,只有Bundle是部署Java应用的实体对象。
Bunlde部署以Jar文件方式进行,其中Jar文件采用zip格式存储了应用以及资源数据,这个格式参考文献[9]Zip File Format。Bundle通常使用.jar后缀,但是为OSGi Bundle保留了一个特殊的MIME type,用于区分普通的Jar文件。MIME type为:application/vnd.osgi.bundle,这个type定义在参考文献[15] OSGi IANA Mime Type。
Bundle的Jar文件内容:
* 包含提供服务所必需的资源文件,这些资源文件可以是java的class文件,或者是HTML文件、帮助文件、图标文件等。一个Bundle Jar文件也可以嵌入其他Jar文件,但是不支持多层嵌套的Jar。
* 包含manifest文件,这个文件描述了Jar文件内容和Bundle信息。该文件是Jar的头文件,提供了Framework安装和激活Bundle时所需的特殊信息。例如,manifest提供了java package的依赖状态信息,这些信息必须要在Bundle运行之前加载。
* 在Jar文件根目录或者子文件夹下的OSGI-OPT目录中可以包含文档信息,这个目录下的内容都是可选的。例如,可以在OSGI-OPT目录下存储Bundle的源代码,而且管理系统可以删除这个文件夹下的内容以减少Framework的存储空间。
当Bundle启动后,这个Bundle可以为安装在OSGi Framework中的Bundle提供功能和服务。
3.2.1 Bundle Manifest Headers
Bundle的描述信息在manifest文件中,这个文件是指Jar中的META-INF/MANIFEST.MF。
Framework定义了OSGi manifest文件头,如Export-Package和Bundle-ClassPath。Bundle开发人员可以使用这些描述信息,Manifest头文件必须严格遵守参考文献[10] Manifest Format。
Framework必须实现:
* 处理manifest的主要部分。Manifest中的个别部分只用于Bundle的签名验证。
* 忽略不可识别的manifest头信息。因此,Bundle开发人员可以在manifest文件中定义额外的附加信息。
* 忽略不可识别的属性和指令。
下面列出了指定的manifest头信息,除非特别申明,所有标记信息都是可选的。
3.2.1.1 Bundle-ActivationPolicy: lazy
Bundle-ActivationPolicy指定了framework第1次如何启动Bundle。
3.2.1.2 Bundle-Activator: com.acme.fw.Activator
Bundle-Activator指定了如何启动和停止Bundle的类,具体参考4.4.5启动Bundle
3.2.1.3 Bundle-Category: osgi, test, nursery
Bundle-Category表示逗号分隔的分类名称。
3.2.1.4 Bundle-ClassPath: /jar/http.jar
Bundle-ClassPath定义了逗号分隔的路径,内容为Jar文件路径和类路径(Bundle内部)。点号(’.’ \u002E)表示Jar的根目录,而且也是默认的。具体参考3.9.1Bundle类路径。
3.2.1.5 Bundle-ContactAddress: 2400 Oswego Road, Austin, TX 74563
Bundle-ContactAddress提供发行者的联系地址。
3.2.1.6 Bundle-Copyright: OSGi (c) 2002
Bundle-Copyright指Bundle的版权信息。
3.2.1.7 Bundle-Description: Network Firewall
Bundle-Description定义了Bundle的简短描述信息。
Bundle-DocURL指Bundle的文档链接地址。
3.2.1.9 Bundle-Icon: /icons/acme-logo.png;size=64
Bundle-Icon是可选项,提供了不同大小的icon图标URL列表来表示这个Bundle,下面的属性是允许的:
- size-(integer),指定了icon图标的水平像素大小,建议始终包含一个64x64的icon。 icon的URL关联Bundle,也就是说,如果提供URL,那么需要提供一个绝对地址URL。否则,在Jar文件的路径入口处,可能会使用到任意链接片段。这个头信息的实现至少需要支持Portable Network Graphics (PNG) 格式, 具体参考文献 [17] Portable Network Graphics
(PNG) Specification (Second Edition)。
Bundle-License提供了一个机器可读的许可证信息(license),这个是可选项。提供这个头信息的目的是多个组织自动化处理许可证,例如Bundle被使用前的许可证验证。而且这个头结构提供了唯一的license命名,license信息是被读者可以阅读的,但是这个头信息只是纯粹的信息管理代理,OSGi Framework并不会处理。
语法如下:
Bundle-License ::= ’<<EXTERNAL>>’ |
( license ( ’,’ license ) * )
license ::= name ( ’;’ license-attr ) *
license-attr ::= description | link
description ::= ’description’ ’=’ string
link ::= ’link’ ’=’ <url>
头信息有如下属性:
- name-为license提供了一个全局唯一的名字,最好是互联网范围下唯一命名,但是至少需要遵守互联网中的其他条款。<<EXTERNAL>>表示本文不包含任何license信息,但是授权信息在其他地方提供,这也是该头文件的默认内容。 Bundle的客户端能识别相同名字的license引用了同一个许可证。例如,为了最小化点击license,name需要使用URL,他不应该局限于翻译者,这个URL必须存在而且指明最新版本的许可证信息。建议使用参考文献[18]Open
Source Initiative的URL规范,其他许可证建议使用如下结构,这不是强制的: http://<domain-name>/licenses/<license-name>-<version>.<extension>
- description-(可选项),提供了许可证的描述信息。这个简要描述可以在UI中的列表选择框可以用到。
- link-(可选项),提供了一个URL页面定义或者解释许可证。如果这个链接地址不存在,URL可以关联Bundle根目录下的某一个具体文件。 如果Bundle-License声明不存在,并不意味着这个Bundle没有许可证。许可证可以在Bundle外部,<<EXTERNAL>>内容会被认可。这个头信息没有任何法律支撑,在使用许可证之前请咨询律师。
3.2.1.11 Bundle-Localization: OSGI-INF/l10n/bundle
Bundle-Localization包含Bundle的本地化文件地址,默认值是OSGI-INF/l10n/bundle。其他翻译文件如OSGI-INF/l10n/bundle_de.properties, OSGI-INF/l10n/bundle_nl.properties,具体参考3.11本地化。
3.2.1.12 Bundle-ManifestVersion: 2
Bundle-ManifestVersion定义了Bundle需要遵守本规范的规则,默认值是1表示第3个版本的Bundle,2表示第4个版本的或者更后发布的版本,也可以为OSGi Framework定义更高的数字。
3.2.1.13 Bundle-Name: Firewall
Bundle-Name定义了一个有可读性的名字来表示Bundle,名字应该是简短易读而且没有空格的。
3.2.1.14 Bundle-NativeCode: /lib/http.DLL; osname = QNX; osversion = 3.1
Bundle-NativeCode包含本地代码库的规范,具体可以参考3.10加载本地代码库
3.2.1.15 Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0
Bundle-RequiredExecutionEnvironment指示在OSGi framekwork上必须支持的可执行环境,用逗号分隔。具体参考3.4可执行环境,这头信息不建议使用。
3.2.1.16 Bundle-SymbolicName: com.acme.daffy
Bundle-SymbolicName为Bundle提供了一个全局唯一的名字。在framework中多次安装Bundle时,Bundle SymbolicName和version必须唯一。SymbolicName是基于反域名解析的。具体可参考3.6.2Bundle标志符一节,这部分头是必须的。
Bundle-UpdateLocation指定了Bundle的更新URL,如果Bundle需要更新,那么会使用这个地址更新Bundle。
3.2.1.18 Bundle-Vendor: OSGi Alliance
Bundle-Vendor描述Bundle的发行者信息。
3.2.1.19 Bundle-Version: 1.1
Bundle-Version表示Bundle的版本信息,默认值是0.0.0 ;具体参考3.2.5版本(verison)
3.2.1.20 DynamicImport-Package: com.acme.plugin.*
DynamicImport-Package包含了一个逗号分隔的动态导入包清单。具体可参考3.9.2 Dynamic Import Package(动态导入包)
3.2.1.21 Export-Package: org.osgi.util.tracker;version=1.3
Export-Package包含导出package声明信息。具体可参考3.6.5 Export Package
3.2.1.22 Export-Service: org.osgi.service.log.LogService
不建议使用
3.2.1.23 Fragment-Host: org.eclipse.swt; bundle-version="[3.0.0,4.0.0)"
Fragment-Host定义了本片段中的主Bundle,参考3.14.1片段主体(Fragment-Host)
3.2.1.24 Import-Package: org.osgi.util.tracker,org.osgi.service.io;version=1.4
Import-Package声明Bundle导入的包。具体可参考3.6.4 Import-Package
3.2.1.25 Import-Service: org.osgi.service.log.LogService
不建议使用
3.2.1.26 Provide-Capability: com.acme.dict; from=nl; to=de; version:Version=1.2
Provide-Capability描述了Bundle提供的一组Capability,具体可参考3.3依赖
3.2.1.27 Require-Bundle: com.acme.chess
Require-Bundle描述了该Bundle import了其他Bundle export的内容。具体可参考3.13 Require-Bundle
3.2.1.28 Require-Capability: osgi.ee; filter:="(&(osgi.ee=AcmeMin)(version=1.1))"
Require-Capability描述了一个Bundle需要其他Bundle提供的capability。具体可参考3.3依赖
3.2.2自定义Header
manifest有一个极好的空间用来提供Bundle相关的元数据,这规则对于OSGi联盟和其他组织都有效。由于历史原因,OSGi联盟声明了默认namespace指定OSGi header,如Bundle、Import、Export等。其他组织如果想使用这些header信息,为了避免与OSGi联盟定义的头信息冲突,可以采用自定义头前缀x-,例如x-LazyStart。
OSGi联盟外部组织可以在OSGi命名空间中请求头信息,OSGi联盟注册的name可以参考文献[16] OSGi Header Namespace Registry.
3.2.3 Header值语法
每一个Manifest header信息都有自己的语法,语法定义在参考文献[11] W3C EBNF。接下来的部分定义了一些常用的规则。
3.2.4 通用Header语法
许多Manifest header都有一个通用的语法,语法表示式如下:
header ::= clause ( ’,’ clause ) *
clause ::= path ( ’;’ path ) *
( ’;’ parameter ) * // 具体参考 1.3.2
参数可以是指令或者属性。一般指令在框架中用于潜在语义支持,属性用于匹配和比较。
3.2.5 版本(Version)
version规范在很多地方都会用到,version说明采用以下的结构:
version ::=
major( '.' minor ( '.' micro ( '.' qualifier )? )? )?
major ::= number // 具体参考 1.3.2
minor ::= number
micro ::= number
qualifier ::= ( alphanum | ’_’ | '-' )+
version内容不能有任何空白,默认值是0.0.0。version对应的API参考10.1.32 Version calss
3.2.6 版本范围
版本范围采用数值区间的方式描述,具体可以参考文献[12] Mathematical Convention for Interval Notation.版本范围的语法如下:
version-range ::= interval | atleast
interval ::= ( '[' | '(' ) floor ',' ceiling ( ']' | ')' )
atleast ::= version
floor ::= version
ceiling ::= version
如果version的值只有一个,那么这个表示范围区间[version,∞)。无版本信息,表示区间值为[0.0.0,∞)。
注意在表示版本范围的时候,用双引号包含 版本开区间,用逗号分隔版本。例如,
Import-Package: com.acme.foo;version="[1.23, 2)", «
com.acme.bar;version="[4.0, 5.0)"
在下表中,展示了每个范围区间用法,x表示可以在区间中使用的值:
如:
[1.2.3, 4.5.6) 1.2.3 <= x < 4.5.6
[1.2.3, 4.5.6] 1.2.3 <= x <= 4.5.6
(1.2.3, 4.5.6) 1.2.3 < x < 4.5.6
(1.2.3, 4.5.6] 1.2.3 < x <= 4.5.6
1.2.3 1.2.3 <= x
版本范围的API支持参考 VersionRange class
3.2.7 Filter语法
OSGi规范中广泛使用了filter表示式。filter表达式为约束提供了简洁的表达方式。filter字符串过滤语法基于LDAP查找过滤器语法,具体参考文献[5] A String Representation of LDAP Search Filters. 需要注意的式LDAP查找过滤器的字符串表达语法已经由RFC 2254代替了RFC 1960,只是添加了扩展匹配。但是OSGi框架的API不提供这个语法支持。
一个LDAP查找过滤器使用前缀形式的字符串表示,采用如下的语法定义:
filter ::= ’(’ filter-comp ’)’
filter-comp ::= and | or | not | operation
and ::= ’&’ filter-list
or ::= ’|’ filter-list
not ::= ’!’ filter
filter-list ::= filter | filter filter-list
operation ::= simple | present | substring
simple ::= attr filter-type value
filter-type ::= equal | approx | greater-eq | less-eq
equal ::= ’=’
approx ::= ’~=’
greater-eq ::= ’>=’
less-eq ::= ’<=’
present ::= attr ’=*’
substring ::= attr ’=’ initial any final
initial ::= () | value
any ::= ’*’ star-value
star-value ::= () | value ’*’ star-value
final ::= () | value
value ::= <see text>
attr ::= <see text>
attr的内容表示用key或者name。属性名称是不区分大小写的,即cn和CN是指同一个属性。attr中不能有这个字符:'=', '\>', '\<', '~', '(' 或 ')',属性名称中可以有空格,但是开始和末尾的空格会被忽略。
value通过和过滤属性的值进行比较而得到的部分值。
如果value中间包含字符(’\’ \u005C), ('*' \u002A), 左括号(’(’ \u0028)或者右括号(')' \u0029)中的任何一个,那么必须使用反斜杠进行转义处理。在value中,空格是有含义的,空格在Character.isWhiteSpace()中定义。
虽然substring和现有产品中都可以生成attr=*结构,但是这种结构只是用于表示一个现有过滤器。
substring只能是String、String[]的属性,在其他情况下,结果一定是错误的。
近似计算filter类型(’~=’)具体实现由framework实现,但是至少要忽略大小写和空格,这个功能需要使用探测法和其他一些智能逼近的代码实现。
filter求值之后,会对具体的属性值和filter的值进行比较。
对于值的比较不是直接进行的,字符串的比较和数字比较不一样,value的比较属于多值字符串比较。
Property必须是字符串类型,object class中的property值定义了比较类型,这些属性值需要使用如下类型:
type ::= scalar | collection | array
scalar ::= String | Integer | Long | Float
| Double | Byte | Short
| Character | Boolean
primitive ::= int | long | float | double | byte
| short | char | boolean
array ::= <Array of primitive>
| <Array of scalar>
collection ::= <Collection of scalar>
下面的规则用于进行比较:
- String – 使用字符串进行比较
- Integer, Long, Float, Double, Byte, Short, Character objects and primitives –利用数字进行比较,这个值比较前应该先去除多余的空格。
- Boolean object –利用Boolean.valueOf(value).booleanValue()定义的值进行比较。在使用valueOf方法前应先去除value中多余的空格。
- Array 或者 Collection–根据保存内容的具体类型进行比较,内容可能有多种类型或者为null。如果以前保存不是上述类型,就会创建一个对应的实例化对象,然后再根据下述顺序进行比较:
- 通过public static type valueOf(String value)来比较。
- 实例化只带一个String参数的构造函数对象来进行比较 如果构造函数中的任何一个方法有效,那么Framework必须通过带String参数构造函数来实例化一个临时对象。如果构造函数和函数不能直接访问,那么将使用setAccessible方法打开访问权限。
Object对象比较使用如下比较属性的方式进行:
- Comparable对象–通过Comparable接口实现进行比较
- 其他对象–使用equal方式比较
如果上面没有一条规则可以对应,那么比较结果为false。
如果一个属性具有多个值,那么filter只要满足其中一个值即可成立,例如:
Dictionary dict = new Hashtable();
dict.put( "cn", new String[] { "a", "b", "c" } );
dict可以被filter(cn=a)或者(cn=b)匹配满足。
Service属性定义通常使用基础类型、collection类型、array类型。在这些情况下,使用简单的+放到type后面,例如String+,表示一个String,或者String[],或者Collection<String>。
filter支持的API可以参考FrameworkUtil.createFilter(String)或者BundleContext.createFilter(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提供了一个动态应用程序的执行...
osgi framework 5.0说明文档 osgi插件式框架,在java中得到成功应用,并应用于eclipse框架
包含翻译后的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最新规范第四版, 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页)
spring-osgi-1.2.0-rc1-with-dependencies.zip
包含翻译后的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、...
osgi.core-5.0.0,osgi.enterprise-5.0.0
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,以前的应用可以直接运行在新版本的框架中。