- 浏览: 502362 次
文章分类
最新评论
OSGi规范中文版(第5版 core R5.0.0)-第3章模块层(Module Layer)3[译]
3.5 类加载机制
许多Bundle可以共享一个虚拟机(VM),具体可参考[1] Java Virtual Machine Specification, Second Edition。在VM内部,Bundle可以与其他Bundle之间隐藏package/class,以及共享package。
隐藏和共享package的关键因素由java类加载器实现,类加载器则通过bundle-space详细定义的规则加载类。每一个Bundle只会有一个单独的类加载器,类加载的代理网络结构模型如图3.4。
图 3.4 类加载代理模型
类加载器可以通过如下方式加载class和resource:
- Boot class path – boot classpath包含java.* package和对应的实现package。
- Framework class path –Framework通常有一个独立的类加载器,加载Framework实现的类以及关键服务接口。
- Bundle Space –Bundle space由一系列相关的JAR文件组成,或者是紧密相关的JAR文件片段(具体可参考3.14Fragment Bundles)
类空间是指一个给定的bundle类加载器可以访问到的所有的类。故,一个指定的Bundle类空间包含如下内容:
- parent类加载器(通常来自boot classpath中的java.* package)
- Import package
- Required bundle
- Bundle的class path(private package)
- 附加的fragment
类空间必须具有一致性,也就是说不能存在同名的2个class(为了防止类声明错误),但是,在OSGi框架中,不同的类空间可以存在同名的类。在模块层,支持不同版本的类,加载到相同的虚拟机中。
图3.5展示了BundleA的类空间,BundleA的右侧顶部不在类空间内,因为这部分描述被export替代的内容BundleA自身不可访问。
图3.5 类空间
在类加载过程中,Framework需要完成一系列的职责,在使用Bundle之前,必须对共享的package约束关系进行解析,选择一个最合适的类并创建wiring,具体可以参考3.8解析过程一节,在3.9运行期类加载一节中也描述了一些运行期的特性。
3.5.1 解析过程(resolving)
Framework必须支持Bundle解析。解析过程是指如何处理import包和export包的wire关系。解析过程需要满足约束条件(manifest中的Import/Export Package, Require-Bundle, Fragment-Host),而且resolving必须在Bundle中的代码加载或运行之前。
Wire是指exporter 和importer(都是Bundle)之间的实际关联关系,wire还关联到一系列的约束条件,这些约束都在manifest中定义,一个有效的wire必须满足对应所有约束,下图3.6描述了wiring模型的类结构
图3.6 wiring模型的类结构示例
3.6 Metadata解析
这一节定义了manifest header为resolver提供的metadata。
3.6.1 Bundle-ManifestVersion
Bundle manifest必须指定version,而且需要遵循OSGi manifest header语法,于是这个version由Bundle-ManifestVersion header提供。使用本规范以及后续版本的Bundle必须指定Bundle-ManifestVersion,语法如下:
Bundle-ManifestVersion ::= number // See 1.3.2
Framework中Bundle的manifest版本必须是’2’,以前版本Bundle的manifest版本为’1’,通常在这样的情况manifest中是无法表描述的。因此,如果版本值不为’2’时,Framework必须明确指明支持后续版本,否则都是无效的标记。
OSGi Framework的实现也可以支持没有Bundle-ManifestVersion的manifest,这样可以与Framework 1.2兼容。
版本为’2’的Bundle必须指定Bundle的Symbolic Name,而且不需要指定Bundle的版本,这个header头可以有默认值。
3.6.2 Bundle-SymbolicName
Bundle-SymbolicName manifest header必须指定。通过Bundle的symbolic name和bundle version确定一个唯一的Bundle;也就是说2个Bundle有同样的symbolic name和bundle version,那么这2个Bundle在Framework中是同一个Bundle。具体参考4.4.1 Bundle标识符
唯一的symbolic name由开发者确定(manifest中的Bundle-Name设计需要具有可读性),Bundle-SymbolicName语法如下:
Bundle-SymbolicName ::= symbolic-name
( ';' parameter ) * // See 1.3.2
Framework必须识别如下Bundle-symbolicName中的指令:
- singleton –表示这个Bundle只有一个版本可以resolve。如果这个值是true,那么表示这是一个单例的Bundle,默认值是false。当同名并且设置为singleton的Bundle的多个版本同时安装在Framework中时,那么Framework最多只能对一个Bundle进行resolve。这是如果2个Bundle的symbolic name相同,那么singleton的Bundle并不会影响到非singleton的Bundle的处理。
- fragment-attachment –定义了哪些fragment可以附加到Bundle上,参考3.14Bundle片段一节,下面定义了哪些值是合法的:
- always –片段可以在host解析完成之后,或者解析过程中附加上去。
- never –不允许附加片段
- resolve-time –片段必须在解析过程中附加
- mandatory –提供mandatory属性列表,表示如果这些不是专门用于requirement (Require-Bundle, Fragment-Host),那么Bundle不会被匹配,具体参考3.7.7 Mandatory属性
- bundle-version –Bundle-Version header值或者0,如果没有这个header,那么表示此属性设置是错误的。 示例: Bundle-SymbolicName: com.acme.foo;singleton:=true
3.6.3 Bundle-Version
Bundle-Version是一个可选header,默认值是0.0.0
示例:Bundle-Version ::= version // 参考 3.2.5
如果小版本号(minor)和微版本号(micro)没有指定,那么默认值为0。如果限定部分没有指定,那么默认值是空字符串("")。
版本是可以进行比较的,比较规则按主版本号、小版本号、微版本号的顺序依次进行。最后是字符串的限定符比较。
示例:
Bundle-Version: 22.3.58.build-345678
3.6.4 Import-Package
Import-Package header定义了共享包的import约束。Import-Package的语法如下:
Import-Package ::= import ( ',' import )*
import ::= package-names ( ';' parameter )*
package-names ::= package-name
( ';' package-name )* // 参考 1.3.2
在header中可以定义多个import package,每条import定义描述了一个bundle中单独的package,多个package以分号方式分割。
Import package指令如下:
- resolution – 如果值是mandatory,那么这个package必须被resolve,这个是默认值。如果mandatory的package不能被resolve,那么这个Bundle resolve会失败。Optional表示这个package是可选的。具体参考可选3.7.4 Package一节。 开发者可以指定特定的匹配属性,具体参考3.7.6 属性匹配.这些特定的匹配属性预定义如下:
- version – 选择export package版本的版本范围,语法定义在3.2.6 版本范围。更多版本选择信息参考3.7.3 语义版本。如果这个属性没有指定,那么默认值是[0.0.0, ∞)。
- specification-version – 这个属性是verison属性的别名,从早期版本中迁移过来。如果version属性已经被指定,那么这2个值必须相等。
- bundle-symbolic-name – Bundle的标记名。在Bundle片段中,这个是指主Bundle的标记名。
- bundle-version – export Bundle的版本范围。默认值是[0.0.0, ∞)。具体参考3.7.3语义版本。在Bundle片段中,这个是指主Bundle的版本。
为了允许import package(除java.开头的package),Bundle必须有PackagePermission[, IMPORT]。更多信息参考package权限一节。
当出现以下任意一个错误时将会终止安装或者更新:
- 一个指令或者属性多次重复出现
- 对同一个package多次重复定义import
- version或者specification-version属性不匹配 正确定义示例如下: Import-Package: com.acme.foo;com.acme.bar; version="[1.23,1.24]";resolution:=mandatory
3.6.5 Export-Package
Export-Package头语法与Import-Package头的语法类似,只是一些指令和属性不同。
Export-Package ::= export ( ',' export )*
export ::= package-names ( ';' parameter )*
package-names ::= package-name ( ';' package-name )* // 参考 1.3.2
这个header允许多个package被export。每条export定义描述了一个bundle中单独的package,多个package以分号方式分割。多个重复定义的export package是允许的(不同的import属性都需要这些不同的export 版本)。
Export指令:
- uses – export package需要使用的package列表。注意值中有逗号使用时,这个值必须被闭合的双引号包含。如果export package被选中,那么resolver必须确保import里的package关联了正确的版本,具体参考3.7.5 package约束。
- mandatory – 逗号分隔的属性名列表。注意值中有逗号使用时,这个值必须被闭合的双引号包含。Bundle import package必须指定mandatory属性匹配的值用于export pakage解析。具体参考3.7.7 Mandatory属性
- include – 逗号分隔对import的可见列表,注意值中有逗号使用时,这个值必须被闭合的双引号包含。具体参考3.7.8 Class Filter
- exclude – 逗号分隔对import的不可见列表,注意值中有逗号使用时,这个值必须被闭合的双引号包含。具体参考3.7.8 Class Filter
以下属性是这节规范的一部分:
- version – package version语法定义在3.2.5 version。默认值是0.0.0
- specification-version – version的别名
另外,特定的匹配属性可以被指定。Framework会自动关联每个export package,export package定义如下属性:
- bundle-symbolic-name –export Bundle的标记名。
- bundle-version – export Bundle的version。 当下面任意的一个条件成立时,安装或者更新将会被终止:
- 一条指令或者多个属性重复出现多次
- bundle-symbolic-name或者bundle-version属性被指定在Export-Package头里。
export定义并不是自动import定义。一个export package但是没有import package的Bundle,将会通过bundle的class path获得package。对于只有export package的Bundle,这个Bundle只能被其他Bundle使用,不会接受从另外一个Bundle来的package,这个Bundle要import package优先从自己的class path中选择。
对于export package,Bundle必须有PackagePermission[, IMPORT]。
示例:
Export-Package: com.acme.foo;com.acme.bar;version=1.23
3.6.6 导入导出package
Bundle之间协作要求使用相同的classloader用于协作类型。如果多个Bundleexport的package放在不相交的类空间,那么他们之间无法协作。当Bundle需要import exported 的package时需要明显改善协作,而这些import允许framework来代替export和import。
不能通过替换来增强协作,导入export package只能工作于没有实现细节API的环境,故只在以下几种情况Import of exported packages:
- export package没有使用私有package。
- 至少有一个私有package引用export package,如果没有这个引用存在,那么这个import是没有意义的。
在实际中,importing exported packages只能使用干净的API实现分离。OSGi服务都是尽可能的设计成独立的。很多库的API和实现混合在一起并且在同一个package下以至不能很好替换API package。导入一个export过的package必须根据兼容性要求提供一个版本范围,无论是consumer或者provider的API。具体参考3.7.3语义版本一节
3.6.7 遗留Bundle
如果Bundles的Bundle-ManifestVersion的值不是2或比2大,则必须按照版本3中定义的header头。框架必须将版本3中的头映射为版本4中合适的header:
- Import-Package –一个引入定义必须修改规范版本属性为版本属性。不含规范属性的引入定义不需要做任何修改,因为版本3中的默认值也是0.0.0
- Export-Package – 一个输出定义必须修改规范版本属性为版本属性。输出定义必须附加指令uses。uses指令必须包含所有为这个给定的bundle引入的和输出的packages。另外,如果package没有引入定义,那么必须为它添加一个含有给定版本的引入定义。
- DynamicImport-Package – 动态引入定义没有变化。 一个bundle的manifest包含了多个版本的混合语法是错误的,并且必须是这个bundle的安装失败。在版本2的headers中,属性specification-version是deprecated的,应该使用version来代替它。
3.7 约束解决
OSGi Framework package resolver提供了一系列的匹配import和export的机制,本节详细描述这些机制。
3.7.1 图表和语法
线(wire)和节点(node)组成图标,和Bundle一样,包含了大量重要信息。在下一节中,采用以下约定来阐述详细信息:
Bundle的名字为A,B,C…(即从A开始的大写字母)。Package名字则使用p, q, r, s, t,...(即从p开始的小写字母)。如果version很重要,那么在后面在一个短横线,如q-1.0。语法A.p表示Bundle A中定义了(import或export) package p。
import采用白色框来表示,export则使用黑色框来表示,没有import和export的包称之为private package,用斜线网格背景表示。
Bundle是一系列关联方框的集合。Bundle之间的关联用线(wire)表示,而约束条件则写在这些线上。
图3.7
例如:
A: Import-Package: p; version="[1,2)"
Export-Package: q; version=2.2.2; uses:=p
Require-Bundle: C
B: Export-Package: p; version=1.5.1
C: Export-Package: r
图 3.8 描述了A,B,C这3个Bundle的关系
图 3.8 Bundle图示例
3.7.2 版本(version)约束
版本约束定义import采用精确的版本号或者版本范围描述来匹配export。
一个import定义必须指定一个(import)版本范围,就像属性version一样,并且输出者必须指定一个(export)版本属性。版本范围匹配规则具体参考3.2.6版本范围一节。
例如以下的import和export定义可以被正常解析:
A: Import-Package: p; version="[1,2)"
B: Export-Package: p; version=1.5.1
如图3.9描述了这个约束关系
图3.9 版本约束
3.7.3 语义版本
版本范围通过编码考虑兼容性,OSGi framework并没有定义具体兼容性编码原则,强烈建议使用下面的语义。
传统意义上,兼容性是指2者之间的相容性,一个是指consumer的代码,另一个是指provider的代码,API兼容性基础设计具体为3部分:
- API 自身
- provider API
- consumer API
Provider API是一个密切相关的API,几乎所有的API变化,都会使得provider需要实现不兼容的新版本的API,然而,API的变化从consumer角度则会有更多的回旋余地。许多API可以改变consumer的向后兼容性,但几乎没有任何API可以改变provider的向后兼容。
provider API和consumer API的兼容规则如下:
- major – 不兼容更新 (consumer API和provider API)
- minor –consumer API向后兼容更新,除了provider API.
- micro – 不影响API的改变,例如,错误的注释.
Consumers和Providers都应该使用他们的编译版本作为基础版本,建议忽略微版本号,当修复部署最近的bug微版本号时会使得系统变得生硬,例如,编译版本4.2.1.V201007221030,基础版本应该为4.2
一个Consumer API应该import基础版本的起始和主版本号的结束,如[4.2,5)。Provider应该import到下一个次版本号的结束,如[4.2,4.3)。
3.7.4 可选package
Bundle可以指明它不需要正确解析的package,但是这个package如果可用则使用之。例如,登录过程是很重要的,但是如果没有登录服务,Bundle也是可以正常运行的。
可选import package可以通过以下方式指明:
- Dynamic Imports –DynamicImport-Package头描述了需要的export package。如果Bundle在调用之前不知道具体的类,大多采用Class.forName方法处理。
- Resolution指令–在import中定义一个resolution指令并且指定一个可选值。如果没有合适的可选package,那么Bundle也是可以正常解析的。 Resolution和DynamicImport这2种机制的区别:对于动态导入,每次加载包中的类都会尝试与动态导入包建立连接,而可选导入包只有在bundle解析的时候才进行连接尝试。导入定义的resolution指令中,它的值可以为mandatory(强制的)或者是optional(可选的)。
- mandatory – (默认值)表示Bundle解析的时候,package必须连接到这个Bundle。
- optional – 指定package没有被连接到时,Bundle也能够被解析,即类加载的时候这个package不会被import进去。
下面的示例显示了Bundle B没有提供正确可匹配版本的情况下,Bundle A也能够被解析.
A: Import-Package: p; resolution:=optional; version=1.6
B: Export-Package: p; q; version=1.5.0
图 3.10 可选import
在Bundle实现中,需要考虑可选package没有加载的情况,如果抛出一个找不到package的异常信息,这可以帮助在Bundle classpath中对package做回退处理。当可选package不能被resolve时,任何通过这个package尝试加载的import package都是不存在的。
Bundle的package类可以通过Bundle classpath或者动态加载。
3.7.5 package约束
一个类可以依赖于其他package中的类。例如,继承自其他package中的类,或者这些类出现在方法声明中,这种情况可以称为一个package使用其他package。这种package之间的关系通过在Export-Package中使用uses指令实现。
例如,org.osgi.service.http依赖使用javax.servlet,他们之间的这个关系描述成org.osgi.service.http;uses:= "javax.servlet"
为了保证类空间的一致性,需要设置Bundle中的每一个package只有对应的一个export。例如,Http服务实现需要继承javax.servlet.http.HttpServlet这个基础类,如果Http服务Bundle需要import版本2.4而实际import了2.1版本时,必然会发生class cast异常。如图3.11
图 3.11 Uses 指令A,B需要使用D中的javax.servlet
如果Bundle从exporter中import package,那么export可以通过uses指令定义一些对其他package的约束。uses指令列出了exporter中依赖的一系列package,这些约束保证了这一系列Bundle对于相同的package共享同一个classloader。
如果importer导入了含有uses约束的package,resolver必须通过约束来建立import和export之间的连接。Exporter也有同样的约束。单个import package和exporter之间可以有很多约束。
implied package约束是指通过递归循环构建的约束集合,Implied package约束不是自动导入。更进一步,implied package约束只包括了必须解析的内容(在import中定义描述的内容)。
如图3.12,Bundle A import package p,这里假设定义的p连接到Bundle B。由于uses指令(这里省略uses指令描述)隐含了对package q的约束。进一步说,假设对package q的import关联到Bundle C,那么也就隐含了对package r和s的约束。接下来,假设C.s和C.r分别连接到Bundle D和E,那么这两个Bundle都将package t添加到Bundle A的依赖包集合中。
图3.12 Implied Packages
为了维护类空间的一致性,Framework必须确保Bundle的import不能和任何Bundle的implied package存在冲突。
例如,Framework必须保证A.t的import定义连接到D.t。这时如果import定义连接到package F.t,这就违背了类空间一致性。由于在Bundle A中同时存在来自Bundle D和F的类,这会导致ClassCastException。或者,如果让所有Bundle都连接到F.t,则也可以解决这个问题。
另一种情况如图3.11,Bundle A import了B中的Http服务,Bundle B包含org.osgi.service.http和the javax.servlet,而Bundle A和Bundle B都有连接到javax.servlet的约束。
下面的uses指令的设置导致不能正常解析示例:
A: Import-Package: q; version="[1.0,1.0]"
Export-Package: p; uses:="q,r",r
B: Export-Package: q; version=1.0
C: Export-Package: q; version=2.0
当A.q连接到B.q,而不是C.q时,这个时候能够解析。如果添加Bundle D则会导致不能解析:
D: Import-Package: p, q; version=2.0
D.q必须连接A.p,但是,A.p中包含uses指令,以至A.q连接到B.q-1.0,而D.q需要2.0版本,这违背了类空间约束。
图3.13描述了这种情况
图3.13 uses指令和解析
3.7.6 属性匹配
属性匹配允许importer和exporter通过说明性方式影响匹配过程处理。为了使得import定义可以解析为export定义,import中定义的属性值必须要和export中定义的属性值匹配。在默认情况下,如果export中包含的属性没有出现在import定义中,匹配过程将会继续进行。如果在export定义中指定了mandatory指令(强制),Framework会在import中强制匹配这些属性。在resolve阶段,对于出现在字段DynamicImport- Package中的任何信息都是会被忽略处理的。
例如,下例的语句是匹配的:
A: Import-Package: com.acme.foo;company=ACME
B: Export-Package: com.acme.foo; company="ACME"; security=false
所有属性值都是通过字符串方式进行比较(忽略属性中开始和结尾部分的空格),除了version和bundle- version属性。version和bundle- version采用版本范围的比较方法。
3.7.7 Mandatory属性(强制属性)
属性有两种类型:mandatory(强制) 和optional(可选)。mandatory属性表示必须匹配的属性。optional属性表示在import时可以不考虑的属性,属性默认值为optional。
exporter可以在export定义中通过mandatory指令指定mandatory属性(指令包含了一个逗号分割的属性名称列表,表示在import描述中必须强制匹配的属性)。如下所示,import package和export package是不匹配的,由于在Bundle A中没有指定security属性:
A: Import-Package: com.acme.foo;company=ACME
B: Export-Package: com.acme.foo; company="ACME"; security=false; mandatory:=security
3.7.8 类过滤
exporter可以在export定义使用include和exclude指令限制类的访问范围。这两条指令的值都是逗号分割的类名列表。需要注意的是,逗号需要用双引号包括起来。类名不能包含package name,而且不能含有后缀.class。即类com.acme.foo.Daffy在指令中名称为Daffy。类名中可以含有通配符(’*’ \u002A)。
include指令,默认值为通配符(’*’ \u002A)(表示匹配所有的名称),即所有的类和资源。
exclude指令,默认值为空(表示没有匹配的名称)。如果指定了这两个指令的值,那么默认值就被覆盖了。
如果满足以下条件,表示类是可见的:
- 在include中匹配一条记录,而且在exclude中没有记录可以匹配
- 在其他情况下,load或者find class失败,classloder会抛出一个无法找到类的异常(ClassNotFoundException)。在include和exclude中,不考虑顺序。 下例是一个可见性示例:必须小心使用filter。例如,模块中的一个新版本需要和旧版本兼容,那么就不应该将旧版本中没有filter的类和资源filter掉。例如,定义的package通常在正式package中有一个实现类,而正式package对定义package有访问权限。
package org.acme.open;
public class Specified {
static Specified implementation;
public void foo() { implementation.foo(); }
}
package org.acme.open;
public class Implementation {
public void initialize(Specified implementation) {
Specified.implementation = implementation;
}
}
对于扩展Bundle的实现类必须是不可见的。这时可以将实现类排除在外,使得只有export Bundle可以访问这个类。export定义的标记描述如:
Export-Package: org.acme.open; exclude:=Implementation
3.7.9 Provider selection
Provider selection允许importer选择一个Bundle作为exporter。如果importer和exporter之间没有任何约束,那么使用Provider selection,而且importer与一个特定的exporter紧密关联,一般情况下是用于Bundle测试。为了降低连接的脆弱性,importer可以指定一个可选的版本范围。
Importer可以通过import的bundle-symbolic-name、bundleversion属性来选择一个exporter,并且在Framework中能够自动为每个export定义提供这些属性,但是这些属性不能在export定义中进行指定。
Export中的bundle-symbolic-name属性是指Bundle的符号名称,对应在header头中的Bundle-SymbolicName。bundle-version对应header头中的Bundle-Version值,默认值是0.0.0。
bundle-symbolic-name采用属性匹配方式,bundle-version则是以版本范围方式比较。Import必须是一个版本范围而export是一个版本号。
示例,下面的定义是可以匹配的:
A: Bundle-SymbolicName: A
Import-Package: com.acme.foo; bundle-symbolic-name=B; bundle-version="[1.41,2.0.0)"
B: Bundle-SymbolicName: B
Bundle-Version: 1.41
Export-Package: com.acme.foo
下面的示例是不能匹配的,因为Bundle B没有指定版本号,默认版本为0.0.0:
A: Bundle-SymbolicName: A
Import-Package: com.acme.foo; bundle-symbolic-name=B; bundle-version="[1.41,2.0.0)"
B: Bundle-SymbolicName: B
Export-Package: com.acme.foo;version=1.42
将package和Bundle强耦合在一起后,通过符号名称来选择一个exporter会导致结果脆弱。例如,如果一个exporter被重构为多个Bundle,那么所有涉及的importer都将需要修改,其他任意属性匹配由于独立性而不存在这个缺陷。
Bundle重构时由符号名称带来的脆弱性问题,可以使用与原Bundle同名的façade Bundle来解决部分问题。
3.8 解析过程
Resolving是指Bundle之间建立连接的处理过程,连接之间的约束由以下条件静态定义:
- 任意一个bundle被resolve时,在相同的namespace下capability中任何一个mandatory requirement都必须匹配
- Required的可执行环境定义在header头Bundle-RequiredExecutionEnvironment
- Native代码
- Import和export package(不考虑DynamicImport-Package)
- Required bundle,具体定义参考3.13 Requiring Bundle
- Fragment,提供内容和定义,在3.14 bundle Fragment有详细定义
Bundle如果满足以下条件,则可以被resolve:
- Execution Environment – 在Bundle-RequiredExecutionEnvironment中至少提供一个可执行环境,具体参考8.2 osgi.ee Namespace
- Native code – native代码依赖具体在Bundle-NativeCode指定,具体参考3.10 Loading Native Code Libraries
解析过程是一个约束求解算法,使用关联关系进行描述,解析过程也是一个求解空间的迭代搜索过程。
如果一个模块(module)在import和export中有相同的package定义,那么Framework需要决定如何选择,首先必须处理重复的import定义,下面是可能的结果:
- external—如果resolve到另一个Bundle的export定义,那么不考虑这个Bundle中的重复export定义。
- internal—如果resolve到这个模块中的export定义,那么不考虑这个模块的重复import定义。
- 无法解析—没有匹配的export定义。这是由于开发者引起的错误,也就是说重复的export定义和对应的import定义不相匹配。
遇到下面的情况Bundle可以被resolve:
- 所有mandatory requirement被满足
- 所有mandatory import有连接
- 所有mandatory required bundle可用以及对应的export有连接
连接建立需要满足以下几个条件:
- importer的版本范围和exporter的版本相匹配。
- importer具有exporter指定的所有强制属性。
- importer的所有属性和exporter的相应属性匹配。
- 如果连接到同一个exporter,那么也就隐式关联到同一个package。
- 连接关联一个合法的exporter。
下面列表定义了优先级别,如果有多个选择,则根据优先级降序排列:
- 一个已经resolve的exporter优先于一个未resolve的exporter。
- 具有更高版本的exporter优先于一个低版本的exporter。
- 具有较低Bundle ID的exporter优先于较高ID的exporter。
相关推荐
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框架
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页)
包含翻译后的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包、...
包含翻译后的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
spring-osgi-1.2.0-rc1-with-dependencies.zip
OSGI越来越受到关注,OSGI R4规范,学习OSGI的首选,并且是中文版
osgi最新jar包org.osgi.core-4.2.0
rpm安装包,rpm -i example.rpm
OSGi原理与最佳实践基于作者多年使用0SGi的经验而编写,涵盖了0SGi从/kfqN深入的知识体系,从OSGi的简介开始,介绍OSGi的作用及基本概念;其后进入OSGi实战,...第11章 先睹为快:OSGi R4.2草稿版 第12章 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 应用程序及 R-OSGi 的实现方式入手,阐述了 R-OSGi 对于 OSGi 规范的实现方式。然后通过一个简单的功能实现由浅入深地讲述传统 OSGi 和 R-OSGi 上的两种不同实现,让您对实际操作加深印象。...
这个版本是OSGi服务平台规范的第四个版本,由OSGi成员公司的代表共同开发完成,这个版本将原来的API扩展到了新的领域,修正了部分现有的API,以前的应用可以直接运行在新版本的框架中。