Version 1.4
3.1 Introduction
The standard Java platform provides only limited support for
packaging, deploying, and validating Java-based applications and
components. Because of this, many Java-based projects, such as JBoss
and NetBeans, have resorted to creating custom module-oriented layers
with specialized class loaders for packaging, deploying, and validating
applications and components. The OSGi Framework provides a generic and
standardized solution for Java modularization.
標(biāo)準(zhǔn)的JAVA平臺(tái)對(duì)打包,部署和驗(yàn)證基于JAVA的應(yīng)用程序和組件僅僅提供了有限的支持。所以許多基于JAVA的項(xiàng)目,例如JBoss和
NetBeans,都通過(guò)編寫(xiě)自己的類(lèi)加載器生成面向模塊的層來(lái)打包,部署和驗(yàn)證應(yīng)用程序和組件。OSGi框架為java模塊化提供了一個(gè)通用的標(biāo)準(zhǔn)的解
決方案。
3.2 Bundles
The Framework defines a unit of modularization, called a bundle. A
bundle is comprised of Java classes and other resources, which together
can provide functions to end users. Bundles can share Java packages
among an exporter bundle and an importer bundle in a well-defined way.
In the OSGi Service Platform, bundles are the only entities for deploying Java-based applications.
A bundle is deployed as a Java ARchive (JAR) file. JAR files are
used to store applications and their resources in a standard ZIP-based
file format. This format is defined by [27] Zip File Format.
A bundle is a JAR file that:
• Contains the resources necessary to provide some functionality.
These resources may be class files for the Java programming language,
as well as other data such as HTML files, help files, icons, and so on.
A bundle JAR file can also embed additional JAR files that are
available as resources and classes. This is however not recursive.
• Contains a manifest file describing the contents of the JAR file
and providing information about the bundle. This file uses headers to
specify information that the Framework needs to install correctly and
activate a bundle. For example, it states dependencies on other
resources, such as Java packages, that must be available to the bundle
before it can run.
• Can contain optional documentation in the OSGI-OPT directory of
the JAR file or one of its sub-directories. Any information in this
directory is optional. For example, the OSGI-OPT directory is useful to
store the source code of a bundle. Management systems may remove this
information to save storage space in the OSGi Service Platform.
Once a bundle is started, its functionality is provided and services
are exposed to other bundles installed in the OSGi Service Platform.
OSGi框架定義了模塊化的單位,稱為bundle。一個(gè)bundle由java類(lèi)和資源組成,它們能給終端用戶使用。在具備良好定義的前提下,導(dǎo)出bundle與引入bundle之間能共享java package。
在OSGi平臺(tái),bundle是用于部署基于java應(yīng)用程序的唯一實(shí)體。
一個(gè)bundle被部署為一個(gè)JAR文件,JAR文件是一個(gè)標(biāo)準(zhǔn)的ZIP格式文件用于保存應(yīng)程序和資源。
一個(gè)bundle文件:
• 包含提供某些功能所需的必要資源。這些資源可能是JAVA類(lèi)文件,也可能是HTML文件,幫助文件,圖標(biāo)等其他文件。一個(gè)bundle jar文件中也能嵌入其他的JAR文件作為資源和類(lèi)文件,當(dāng)然這不能是一個(gè)循環(huán)嵌套。
•
包含一個(gè)manifest文件,用于描述JAR文件的內(nèi)容和提供與bundle相關(guān)的信息。manifest文件使用頭的形式來(lái)指定OSGi框架能正確安
裝和激活bundle所需的信息。例如,它聲明了諸如java包這樣的所依賴的資源,這些java包在bundle運(yùn)行之前必須對(duì)它是可用的。
• 能在OSGI-OPT目錄或其子目錄中包含可選文檔,所有在這個(gè)目錄中的信息都是可選的。例如OSGI-OPT目錄可用來(lái)存放bundle的源代碼。不過(guò)OSGi平臺(tái)管理系統(tǒng)可能會(huì)刪除這些信息用于保存存儲(chǔ)空間
一個(gè)bundle一旦被啟動(dòng),它將給其他已經(jīng)安裝在平臺(tái)中的bundle提供它的功能,暴露它的services
3.2.1 Bundle Manifest Headers
A bundle can carry descriptive information about itself in the
manifest file that is contained in its JAR file under the name of
META-INF/MANIFEST.MF.
The Framework defines OSGi manifest headers such as Export-Package
and Bundle-Classpath, which bundle developers use to supply descriptive
information about a bundle. Manifest headers must strictly follow the
rules for manifest headers as defined in [28] Manifest Format.
A Framework implementation must:
• Process the main section of the manifest. Individual sections of
the manifest are only used during bundle signature verification.
• Ignore unrecognized manifest headers. The bundle developer can define additional manifest headers as needed.
• Ignore unknown attributes and directives.
All specified manifest headers are listed in the following sections. All headers are optional, unless specifically indicated.
一個(gè)bundle可以在manifest文件中攜帶與它自己有關(guān)的描述信息,這個(gè)文件被包含在bundle jar文件中META-INF目錄中名為MANIFEST.MF。
OSGi框架定義的諸如Export-Package 和Bundle-Classpath 的manifest頭是bundle開(kāi)發(fā)者用來(lái)提供與bundle有關(guān)的描述信息,Manifest頭必須嚴(yán)格按照[28]manifest Format中定義的規(guī)則。
一個(gè)實(shí)現(xiàn)框架必須:
• 處理manifest的主片段。manifest中的每一個(gè)片段僅僅在bundle的簽名驗(yàn)證的過(guò)程中使用。
• 忽略為被定義的頭。bundle開(kāi)發(fā)者能根據(jù)需要定義額外的頭。
• 忽略未知屬性和標(biāo)識(shí)
所有被指定的頭都被列在下面的內(nèi)容中。如非特殊說(shuō)明,所有頭都是可選的。
3.2.1.1 Bundle-ActivationPolicy: lazy
The Bundle-ActivationPolicy specifies how the framework should
activate the bundle once started. See Activation Policies on page 85.
框架啟動(dòng)時(shí)如何激活這個(gè)bundle
3.2.1.2 Bundle-Activator: com.acme.fw.Activator
The Bundle-Activator header specifies the name of the class used to start and stop the bundle. See Starting Bundles on page 83.
啟動(dòng)和停止bundle的類(lèi)名
3.2.1.3 Bundle-Category: osgi, test, nursery
The Bundle-Category header holds a comma-separated list of category names.
bundle的類(lèi)別
3.2.1.4 Bundle-Classpath: /jar/http.jar,.
The Bundle-Classpath header defines a comma-separated list of JAR
file path names or directories (inside the bundle) containing classes
and resources. The period ('.') specifies the root directory of the
bundle's JAR. The period is also the default. See Bundle Class Path on
page 49.
定義了以逗號(hào)分隔的jar文件路徑或bundle中包含類(lèi)和資源的目錄的列表。點(diǎn)表示bundle jar的根目錄,它也是默認(rèn)路徑。
3.2.1.5 Bundle-ContactAddress: 2400 Oswego Road, Austin, TX 74563
The Bundle-ContactAddress header provides the contact address of the vendor.
bundle提供者的聯(lián)系方式
3.2.1.6 Bundle-Copyright: OSGi (c) 2002
The Bundle-Copyright header contains the copyright specification for this bundle.
bundle提供者的版權(quán)說(shuō)明
3.2.1.7 Bundle-Description: Network Firewall
The Bundle-Description header defines a short description of this bundle.
bundle的描述
3.2.1.8 Bundle-DocURL: http:/www.acme.com/Firewall/doc
The Bundle-DocURL headers must contain a URL pointing to documentation about this bundle.
bundle的文檔URL
3.2.1.9 Bundle-Localization: OSGI-INF/l10n/bundle
The Bundle-Localization header contains the location in the bundle
where localization files can be found. The default value is
OSGI-INF/l10n/bundle. Translations are by default therefore
OSGI-INF/l10n/bundle_de.properties, OSGI-INF/l10n/bundle_nl.properties,
etc. See Manifest Localization on page 63.
包含了一個(gè)在bundle中可以找到本地化文件的路徑。默認(rèn)值是OSGI-INF/l10n/bundle 。
3.2.1.10 Bundle-ManifestVersion: 2
The Bundle-ManifestVersion header defines that the bundle follows
the rules of this specification. The Bundle-ManifestVersion header
determines whether the bundle follows the rules of this specification.
It is 1 (the default) for Release 3 Bundles, 2 for Release 4 and later.
Future version of the OSGi Service Platform can define higher numbers
for this header.
定義了bundle所遵循的規(guī)范的版本號(hào),這個(gè)頭決定了bundle是否遵循這個(gè)規(guī)范的規(guī)則。
3.2.1.11 Bundle-Name: Firewall
The Bundle-Name header defines a readable name for this bundle. This
should be a short, human-readable name that can contain spaces.
為bundle 定義了一個(gè)可讀取得名字,它應(yīng)該是個(gè)較短的,易識(shí)別的名字,可以包含空格。
3.2.1.12 Bundle NativeCode: /lib/http.DLL; osname = QNX; osversion = 3.1
The Bundle-NativeCode header contains a specification of native code
libraries contained in this bundle. See Loading Native Code Libraries
on page 57.
3.2.1.13 Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0
The Bundle-RequiredExecutionEnvironment contains a comma-separated
list of execution environments that must be present on the Service
Platform. See Execution Environment on page 31.
bundle的可被執(zhí)行環(huán)境
3.2.1.14 Bundle-SymbolicName: com.acme.daffy
The Bundle-SymbolicName header specifies a unique, non-localizable
name for this bundle. This name should be based on the reverse domain
name convention, see Bundle-SymbolicName on page 35. This header must
be set.
為bundle指定了一個(gè)唯一的,非本地化的名字,這個(gè)名字應(yīng)該反轉(zhuǎn)于域名結(jié)構(gòu)。這個(gè)頭必須被指定
The Bundle-UpdateLocation header specifies a URL where an update for
this bundle should come from. If the bundle is updated, this location
should be used, if present, to retrieve the updated JAR file.
指定了該bundle更新的URL。
3.2.1.16 Bundle-Vendor: OSGi Alliance
The Bundle-Vendor header contains a human-readable description of the bundle vendor.
bundle提供者的描述
3.2.1.17 Bundle-Version: 1.1
The Bundle-Version header specifies the version of this bundle. See Version on page 28. The default value is 0.0.0
bundle的版本,默認(rèn)值是0.0.0
3.2.1.18 DynamicImport-Package: com.acme.plugin.*
The DynamicImport-Package header contains a comma-separated list of
package names that should be dynamically imported when needed. See
Dynamic Import Package on page 51.
包含了一個(gè)以逗號(hào)分隔的包名的列表,列表中的包應(yīng)該在需要的時(shí)候被動(dòng)態(tài)引入
3.2.1.19 Export-Package: org.osgi.util.tracker;version=1.3
The Export-Package header contains a declaration of exported packages. See Export-Package on page 37.
聲明被輸出的包
3.2.1.20 Export-Service: org.osgi.service.log.LogService
Deprecated.
3.2.1.21 Fragment-Host: org.eclipse.swt; bundle-version="[3.0.0,4.0.0)"
The Fragment-Host header defines the host bundle for this fragment. See Fragment-Host on page 69
為這個(gè)片段定義一個(gè)主機(jī)bundle
3.2.1.22 Import-Package: org.osgi.util.tracker,org.osgi.service.io;version=1.4
The Import-Package header declares the imported packages for this bundle. See Import-Package Header on page 36.
為這個(gè)bundle聲明引入的包
3.2.1.23 Import-Service: org.osgi.service.log.LogService
Deprecated
3.2.1.24 Require-Bundle: com.acme.chess
The Require-Bundle header specifies the required exports from another bundle. Require-Bundle on page 65
指定所依賴bundle
3.4 Class Loading Architecture
Many bundles can share a single virtual machine (VM). Within this
VM, bundles can hide packages and classes from other bundles, as well
as share packages with other bundles.
The key mechanism to hide and share packages is the Java class
loader that loads classes from a sub-set of the bundle-space using
well-defined rules. Each bundle has a single class loader. That class
loader forms a class loading delegation network with other bundles as
shown in Figure 3.8.
bundles能在同一個(gè)虛擬機(jī)中,在這個(gè)虛擬機(jī)中,bundles能對(duì)其他bundles隱藏包和類(lèi),也能對(duì)其他bundles共享包和類(lèi)。
隱藏和共享包的關(guān)鍵是java class loader通過(guò)良好定義規(guī)則從bundle空間的子集(子class
loader)中加載類(lèi)。每一個(gè)bundle都有一個(gè)class loader,這個(gè)class loader與其他bundles的class
loader形成了一個(gè)類(lèi)加載委派網(wǎng)絡(luò),如圖

The class loader can load classes and resources from:
• Boot class path - The boot class path contains the java.* packages and its implementation packages.
• Framework class path - The Framework usually has a separate class
loader for the Framework implementation classes as well as key service
interface classes.
• Bundle Space - The bundle space consists of the JAR file that is
associated with the bundle, plus any additional JAR that are closely
tied to the bundle, like fragments, see Fragment Bundles on page 68.
A class space is then all classes reachable from a given bundle's
class loader. Thus, a class space for a given bundle can contain
classes from:
• The parent class loader (normally java.* packages from the boot class path)
• Imported packages
• Required bundles
• The bundle's class path (private packages)
• Attached fragments
A class space must be consistent, such that it never contains two
classes with the same fully qualified name (to prevent Class Cast
Exceptions). However, separate class spaces in an OSGi Platform may
contain classes with the same fully qualified name. The modularization
layer supports a model where multiple versions of the same class are
loaded in the same VM.
class loader能夠從以下位置加載類(lèi)和資源:
• boot類(lèi)路徑 - boot類(lèi)路徑包含了java.*的包和它們的實(shí)現(xiàn)包(可以理解為應(yīng)用服務(wù)器的類(lèi)路徑)
• 框架類(lèi)路徑 - 通??蚣軙?huì)有不同的class loader 去加載框架的實(shí)現(xiàn)類(lèi),和主服務(wù)接口類(lèi)。
• bundle空間 - bundle空間由與bundle相關(guān)聯(lián)的jar文件組成,加上其他包含在bundle中的jar文件
那么一個(gè)類(lèi)空間則可以從一個(gè)給定的bundle的class loader中獲取。因此,一個(gè)給定的bundle的類(lèi)空間包含的類(lèi)可以來(lái)自以下方面:
• 父class loader(通常是boot類(lèi)路徑中的java.*包)
• 引入的包
• 所依賴的包
• bundle的類(lèi)路徑(私有包)
• 附加的片段(例如附加的jar包)
一個(gè)類(lèi)空間必須是consistent(用哪個(gè)詞來(lái)形容不可包含相同名字的兩個(gè)元素?),這樣它不能包含2個(gè)具有相同名字的類(lèi)。不過(guò),相同OSGi平臺(tái)中不同的類(lèi)空間可以包含兩個(gè)名字相同的類(lèi)。模塊化層支持一個(gè)類(lèi)的多個(gè)版本被加載在同一個(gè)虛擬機(jī)中。

The Framework therefore has a number of responsibilities related to
class loading. Before a bundle is used, it must resolve the constraints
that a set of bundles place on the sharing of packages. Then select the
best possibilities to create a wiring. See Resolving Process on page 48
for further information. The runtime aspects are described in Runtime
Class Loading on page 49.
因此對(duì)于類(lèi)加載,框架有很多工作要做。在bundle被使用之前,它必須解析一系列bundles上的共享包的約束,然后選擇最佳方式去搭配它們
3.4.1 Resolving
The Framework must resolve bundles. Resolving is the process where
importers are wired to exporters. Resolving is a process of satisfying
constraints. This process must take place before any code from a bundle
can be loaded or executed.
A wire is an actual connection between an exporter and an importer,
which are both bundles. A wire is associated with a number of
constraints that are defined by its importer's and exporter's manifest
headers. A valid wire is a wire that has satisfied all its constraints.
Figure 3.10 depicts the class structure of the wiring model.
框架必須解析bundle。解析是將引入者搭配到輸出者的過(guò)程,也是滿足約束的過(guò)程。這個(gè)過(guò)程必須在bundle中的代碼被加載或執(zhí)行之前進(jìn)行。
搭配,是輸出者與引入者之間的真實(shí)連接,一個(gè)有效的搭配是滿足了所有約束的鏈接。
3.5 Resolving Metadata
The following sections define the manifest headers that provide the metadata for the resolver.
以下章節(jié)定義了為解析者提供元數(shù)據(jù)的manifest頭
3.5.1 Bundle-ManifestVersion
A bundle manifest must express the version of the OSGi manifest
header syntax in the Bundle-ManifestVersion header. Bundles exploiting
this version of the Framework specification (or later) must specify
this header. The syntax of this header is as follows:
一個(gè)bundle的manifest必須在頭Bundle-ManifestVersion中明確表示這個(gè)OSGi manifest頭語(yǔ)法的版本號(hào)。bundle必須使用這個(gè)頭。
Bundle-ManifestVersion ::= number // See 1.3.2
The Framework version 1.3 (or later) bundle manifest version must be’2’.
Bundle manifests written to previous specifications’ manifest syntax are
taken to have a bundle manifest version of '1', although there is no way to
express this in such manifests. Therefore, any other value than ’2’ for this
header is invalid unless the Framework explicitly supports such a later version.
OSGi Framework implementations should support bundle manifests without
a Bundle-ManifestVersion header and assume Framework 1.2 compatibility
at the appropriate places.
Version 2 bundle manifests must specify the bundle symbolic name. They
need not specify the bundle version since this version header has a default
value.
1.3或以后版本的框架中的bundle manifest版本必須是2,以前的版本則為1,因此所有值不是2的頭均為不可用的頭,除非框架明確支持。
OSGi實(shí)現(xiàn)框架應(yīng)該支持不含Bundle-ManifestVersion頭的bundle manifest,并且兼容1.2。
版本2的bundle manifest必須指定bundle標(biāo)記名,可以不用指定bundle版本,因?yàn)榘姹绢^有默認(rèn)值(0.0.0)
3.5.2 Bundle-SymbolicName
The Bundle-SymbolicName manifest header is a mandatory header. The
bundle symbolic name and bundle version allow a bundle to be uniquely
identified in the Framework. That is, a bundle with a given symbolic
name and version is treated as equal to another bundle with the same
(case sensitive) symbolic name and exact version.
The installation of a bundle with a Bundle-SymbolicName and Bundle-Version identical to an existing bundle must fail.
A bundle gets its unique Bundle-SymbolicName from the developer (The
Bundle-Name manifest header provides a human-readable name for a bundle
and is therefore not replaced by this header).
Bundle-SymbolicName 是一個(gè)必須的頭,框架可以使用bundle標(biāo)記名和版本號(hào)來(lái)識(shí)別bundle的唯一性,也就是說(shuō),將給定標(biāo)記名和版本號(hào)的bundle與其他擁有相同標(biāo)記名(區(qū)分大小寫(xiě))和精確版本號(hào)的bundle進(jìn)行比較。
當(dāng)安裝一個(gè)與已經(jīng)存在的bundle具有相同標(biāo)記名和版本號(hào)的bundle時(shí),必須安裝失敗。
一個(gè)bundle的標(biāo)記名是開(kāi)發(fā)者給定的。
The Bundle-SymbolicName manifest header must conform to the following syntax:
Bundle-SymbolicName ::= symbolic-name ( ';' parameter ) * // See 1.3.2
The framework must recognize the following directives for the Bundle-SymbolicName header:
• singleton - Indicates that the bundle can only have a single
version resolved. A value of true indicates that the bundle is a
singleton bundle. The default value is false. The Framework must
resolve at most one bundle when multiple versions of a singleton bundle
with the same symbolic name are installed. Singleton bundles do not
affect the resolution of non-singleton bundles with the same symbolic
name.
• fragment-attachment - Defines how fragments are allowed to be
attached, see the fragments in Fragment Bundles on page 68. The
following values are valid for this directive:
• always - Fragments can attach at any time while the host is resolved or during the process of resolving.
• never - No fragments are allowed.
• resolve-time - Fragments must only be attached during resolving.
For example:
Bundle-SymbolicName: com.acme.foo;singleton:=true
框架必須為頭Bundle-SymbolicName提供以下屬性的支持:
• singleton -
表示該bundle僅僅只能有一個(gè)版本被解析。值為true表示一個(gè)單例bundle,否則為多例。當(dāng)具有相同標(biāo)記名的多個(gè)版本的單例bundle被安裝
的時(shí)候,框架必須最多只能解析一個(gè)bundle。單例bundle的解析不會(huì)影響到其他具有相同標(biāo)記名的非單例bundle。
• fragment-attachment - 定義了片段是如何被附加的,有以下值:
• always - 當(dāng)bundle被解析后或在解析期間,片段始終被附加著
• never - 不允許附加片段
• resolve-time - 片段只能在解析期間被附加
例如:
Bundle-SymbolicName: com.acme.foo;singleton:=true
3.5.3 Bundle-Version
Bundle-Version is an optional header; the default value is 0.0.0.
Bundle-Version ::= version // See 3.2.4
If the minor or micro version components are not specified, they
have a default value of 0. If the qualifier component is not specified,
it has a default value of the empty string ("").
Versions are comparable. Their comparison is done numerically and
sequentially on the major, minor, and micro components and lastly using
the String class compareTo method for the qualifier.
A version is considered equal to another version if the major,
minor, micro, and the qualifier components are equal (using String
method compareTo).
Example:
Bundle-Version: 22.3.58.build-345678
Bundle-Version是一個(gè)可選的頭,它的默認(rèn)值是0.0.0。
如果主版本號(hào)或三級(jí)版本號(hào)部分沒(méi)有被指定,它們將被設(shè)置成默認(rèn)值0. 如果版本界定給沒(méi)有指定(Alpha, Beta等),則為空字符串。
版本號(hào)是可對(duì)比的。這個(gè)比較是通過(guò)major, minor, and micro的順序比較它們的數(shù)字大小,然后使用String類(lèi)的compareTo方法來(lái)比較版本界定來(lái)完成的。
一個(gè)版本和另一個(gè)版本相同意味著major, minor, micro 和 qualifier 都要相同
例如:
Bundle-Version: 22.3.58.build-345678
3.5.4 Import-Package Header
The Import-Package header defines the constraints on the imports of shared packages. The syntax of the Import-Package header is:
Import-Package ::= import ( ',' import )*
import ::= package-names ( ';' parameter )*
package-names ::= package-name( ';' package-name )* // See 1.3.2
The header allows many packages to be imported. An import definition
is the description of a single package for a bundle. The syntax permits
multiple package names, separated by semi-colons, to be described in a
short form.
頭Import-Package定義了對(duì)共享包的引入的約束。語(yǔ)法如下
Import-Package ::= import ( ',' import )*
import ::= package-names ( ';' parameter )*
package-names ::= package-name( ';' package-name )* // See 1.3.2
這個(gè)頭允許很多包被引入。一個(gè)引入的定義是對(duì)一個(gè)bundle的一個(gè)包的描述。這個(gè)語(yǔ)法允許以分號(hào)隔開(kāi)的多個(gè)包名被描述在這個(gè)結(jié)構(gòu)中。
Import package directives are:
• resolution - Indicates that the packages must be resolved if the
value is mandatory, which is the default. If mandatory packages cannot
be resolved, then the bundle must fail to resolve. A value of optional
indicates that the packages are optional. See Optional Packages on page
42.
The developer can specify arbitrary matching attributes. See
Attribute Matching on page 45. The following arbitrary matching
attributes are predefined:
• version - A version-range to select the exporter's package
version. The syntax must follow Version Ranges on page 28. For more
information on version selection, see Version Matching on page 41. If
this attribute is not specified, it is assumed to be [0.0.0, ∞).
• specification-version - This attribute is an alias of the version
attribute only to ease migration from earlier versions. If the version
attribute is present, the values must be equal.
• bundle-symbolic-name - The bundle symbolic name of the exporting
bundle. In the case of a Fragment bundle, this will be the host
bundle's symbolic name.
• bundle-version - A version-range to select the bundle version of the
exporting bundle. The default value is [0.0.0, ∞). See Version Matching
on page 41. In the case of a Fragment bundle, the version is from the
host bundle.
引入包有以下指令:
• resolution - 如果值為mandatory,表示這個(gè)包必須被解析,這是默認(rèn)值。如果一個(gè)mandatory包不能被解析,那么這個(gè)bundle將解析失敗。值optional表示包是可選的。
開(kāi)發(fā)者可以指定專有匹配屬性:
• version - 一個(gè)選擇輸出包版本的版本范圍。語(yǔ)法必須遵循28頁(yè)(原規(guī)范中的28頁(yè))中版本范圍的語(yǔ)法。如果這個(gè)屬性沒(méi)有被指定,默認(rèn)值為[0.0.0, ∞),就是所有版本都可以用。
• specification-version - 這個(gè)屬性是version的別名,僅僅只是為了使升級(jí)更簡(jiǎn)單(從早期版本移植過(guò)來(lái))。如果version被指定,這兩個(gè)屬性的值必須相等。
• bundle-symbolic-name - 輸出bundle的標(biāo)記名。在具有片段bundle的例子中,這個(gè)值是宿主bundle的標(biāo)記名。
• bundle-version - 輸出bundle的版本范圍。在具有片段bundle的例子中,這個(gè)值是宿主bundle的版本范圍。
In order to be allowed to import a package (except for packages
starting with java.), a bundle must have
PackagePermission[<package-name>, IMPORT]. See PackagePermission
for more information. An error aborts an installation or update when:
• A directive or attribute appears multiple times, or
• There are multiple import definitions for the same package.
Example of a correct definition:
Import-Package: com.acme.foo;com.acme.bar;
version="[1.23,1.24]";
resolution:=mandatory
為了允許引入一個(gè)包,一個(gè)bundle必須有PackagePermission[<package-name>, IMPORT]. 當(dāng)下列情況發(fā)生時(shí)必須終止安裝或更新bundle:
• 一個(gè)指令或?qū)傩猿霈F(xiàn)多次,或
• 多次定義對(duì)同一個(gè)包的引入
正確定義的列子:
Import-Package: com.acme.foo;com.acme.bar;
version="[1.23,1.24]";
resolution:=mandatory
3.5.5 Export-Package
The syntax of the Export-Package header is similar to the
Import-Package header; only the directives and attributes are different.
Export-Package ::= export ( ',' export )*
export ::= package-names ( ';' parameter )*
package-names ::= package-name ( ';' package-name )*// See 1.3.2
The header allows many packages to be exported. An export definition
is the description of a single package export for a bundle. The syntax
permits the declaration of multiple packages in one clause by
separating the package names with a semi-colon. Multiple export
definitions for the same package are allowed for example, when
different attributes are needed for different importers.
頭Export-Package的語(yǔ)法與Import-Package類(lèi)似。僅僅只是一些指令和屬性不同
這個(gè)頭允許包被輸出。一個(gè)輸出的定義是對(duì)為一個(gè)bundle輸出一個(gè)包的描述。這個(gè)語(yǔ)法允許將輸出多個(gè)包的聲明定義在一個(gè)以分號(hào)分隔的子句中。對(duì)同
一個(gè)包的多個(gè)輸出定義是允許的,例如,對(duì)于不同的引入者,需要使用不同的屬性的時(shí)候。(比如2個(gè)引入者需要的是2個(gè)不同的這個(gè)bundle的版本,但是這
個(gè)bundle對(duì)這2個(gè)引入這都可用,那么就以2個(gè)版本的形式輸出)
Export directives are:
• uses - A comma-separated list of package names that are used by
the exported package. Note that the use of a comma in the value
requires it to be enclosed in double quotes. If this exported package
is chosen as an export, then the resolver must ensure that importers of
this package wire to the same versions of the package in this list. See
Package Constraints on page 43.
• mandatory - A comma-separated list of attribute names. Note that the
use of a comma in the value requires it to be enclosed in double
quotes. A bundle importing the package must specify the mandatory
attributes, with a value that matches, to resolve to the exported
package. See Mandatory Attributes on page 45.
• include - A comma-separated list of class names that must be visible
to an importer. Note that the use of a comma in the value requires it
to be enclosed in double quotes. For class filtering, see Class
Filtering on page 46.
• exclude -A comma-separated list of class names that must be invisible
to an importer. Note that the use of a comma in the value requires it
to be enclosed in double quotes. For class filtering, see Class
Filtering on page 46.
輸出指令有:
• uses - 給輸出包使用的以逗號(hào)分隔的包名的列表。注意值中逗號(hào)的使用,它需要被雙引號(hào)括起來(lái)。如果一個(gè)輸出包被引入包選中,那么解析者(框架)需要確保引入包引入的是列表中與之版本號(hào)相同的包。
• mandatory - 以逗號(hào)分隔的屬性名的列表。注意值中逗號(hào)的使用,它需要被雙引號(hào)括起來(lái)。一個(gè)引入這個(gè)包的bundle必須指定mandatory屬性和一個(gè)匹配值,用于解析到輸出包。
• include - 以逗號(hào)分隔的必須對(duì)引入者可見(jiàn)的類(lèi)名的列表。
• exclude -以逗號(hào)分隔的必須對(duì)引入者不可見(jiàn)的類(lèi)名的列表
The following attribute is part of this specification:
• version - The version of the named packages with syntax as defined
in Version on page 28. It defines the version of the associated
packages. The default value is 0.0.0.
• specification-version - An alias for the version attribute only to
ease migration from earlier versions. If the version attribute is
present, the values must be equal.
Additionally, arbitrary matching attributes may be specified. See
Attribute Matching on page 45. The Framework will automatically
associate each package export definition with the following attributes:
• bundle-symbolic-name - The bundle symbolic name of the exporting
bundle. In the case of a Fragment bundle, this is the host bundle's
symbolic name.
• bundle-version - The bundle version of the exporting bundle. In the
case of a Fragment bundle, this is the host bundle's version.
以下屬性是這部分規(guī)范的一部分:
• version - 以定義在page28中的語(yǔ)法命名的包的版本號(hào)。它定義了關(guān)聯(lián)的包的版本。默認(rèn)值0.0.0。
• specification-version - 屬性version的別名.
另外,專有匹配屬性可以被指定??蚣軙?huì)自動(dòng)以下列屬性關(guān)聯(lián)每一個(gè)包的輸出定義(這個(gè)屬性只是出現(xiàn)在importer中,用來(lái)匹配輸出包,而不能出現(xiàn)在輸出包中):
• bundle-symbolic-name - 輸出bundle的標(biāo)記名。在含有片段的例子中,是宿主bundle的標(biāo)記名。
• bundle-version - 輸出bundle的版本。在含有片段的例子中,是宿主bundle的版本。
An installation or update must be aborted when any of the following conditions is true:
• a directive or attribute appears multiple times
• the bundle-symbolic-name or bundle-version attribute is specified in the Export-Package header.
An export definition does not imply an automatic import definition.
A bundle that exports a package and does not import that package will
get that package via its bundle class path. Such an exported only
package can be used by other bundles, but the exporting bundle does not
accept a substitution for this package from another bundle.
In order to export a package, a bundle must have PackagePermission[<package>, EXPORT].
Example:
Export-Package: com.acme.foo;com.acme.bar;version=1.23
當(dāng)出現(xiàn)以下條件時(shí),安裝或更新必須被終止:
• 一個(gè)指令或?qū)傩猿霈F(xiàn)多次
• bundle-symbolic-name 或 bundle-version 屬性被指定在 Export-Package 中.
一個(gè)輸出定義并非一個(gè)自動(dòng)引入定義。一個(gè)輸出了一個(gè)包的bundle并不會(huì)引入這個(gè)包,而是通過(guò)bundle
classpath來(lái)獲取這個(gè)包,這樣一個(gè)輸出了的包只能被其他bundles使用,但是輸出bundle不會(huì)接受從另外一個(gè)bundle而來(lái)的這個(gè)包的
替代品。(理解為,一個(gè)bundle含有package
com.foo,自己需要這個(gè)package,也輸出這個(gè)package,而一個(gè)bundle也同樣輸出這個(gè)package,第一個(gè)bundle不會(huì)使用
第二個(gè)bundle中的package,而是通過(guò)classpath使用自己的那個(gè)package)
3.5.6 Exporting and Importing a Package
Exporting a package does not imply the import of that same package
(in Release 3, an export did imply an import). The reason for this
separation is that it enables a bundle to provide a package to other
bundles without having to take into account that the exported package
could be substituted by the resolver with the same package from another
bundle. This is a common case when an application consists of a set of
closely intertwined bundles where implementation packages are provided
to other bundles.
輸出一個(gè)包并不意味著對(duì)這個(gè)包的引入(不過(guò)在第三版中,輸出意味著引入)。這樣做的原因是使一個(gè)bundle為其他bundles提供
package,不需要考慮這個(gè)包會(huì)被解析者以其他bundle中相同的package替換。這在一個(gè)應(yīng)用程序是由一系列相互引用其實(shí)現(xiàn)包的bundle
的例子中是很常見(jiàn)的。
The substitution of packages is crucial for the inter-operability of
bundles. In Java, bundles can only inter-operate when they use the same
class loaders for the same classes. Therefore, two bundles that both
export the same package, but do not import it, cannot share objects
from that package. This is very important for a collaboration mechanism
like the Service Layer. Bundles can only use the same service objects
if their classes and interfaces come from the same class loaders.
包的替換對(duì)于bundles的內(nèi)部運(yùn)作能力是很重要的。在java,bundles的內(nèi)部操作僅僅只能當(dāng)它們?yōu)橄嗤腸lasses使用相同的
class
loader才能進(jìn)行。因此,2個(gè)bundles,輸出了相同的package,但是不能引入它,不能從它那獲取共享對(duì)象。這對(duì)像Service
Layer這樣的協(xié)作機(jī)制來(lái)說(shuō)是很重要的。Bundles僅僅只能使用相同的service對(duì)象,如果他們的類(lèi)和接口來(lái)自相同的class
loaders。
Bundles should import exported packages, allowing the resolver to
substitute packages that contain interfaces and other shared types.
This substitution allows bundles to inter-operate through the service
registry and other mechanisms. Additionally, the import should be as
unconstrained as possible to allow the resolver maximum flexibility.
bundles應(yīng)該引入輸出的packages,允許解析者替換那些包含了接口和其他共享對(duì)象的packages。這個(gè)替換允許bundles通過(guò)service注冊(cè)和其他機(jī)制來(lái)進(jìn)行內(nèi)部操作。另外,這個(gè)引入應(yīng)該被盡可能不受限制而是解析者獲得最大的靈活性。
3.5.7 Interpretation of Legacy Bundles 遺留bundle
Bundles that are not marked with a Bundle-ManifestVersion that
equals 2 or more must treat the headers according the definitions in
the Release 3. More specifically, the Framework must map the Release 3
headers to the appropriate Release 4 headers:
• Import-Package – An import definition must change the
specification version attribute to the version attribute. An import
definition without a specification version needs no replacement since
the default version value of 0.0.0 gives the same semantics as Release
3.
• Export-Package – An export definition must change the specification
version attribute to the version attribute. The export definition must
be appended with the uses directive. The uses directive must contain
all imported and exported packages for the given bundle. Additionally,
if there is no import definition for this package, then an import
definition for this package with the given version must be added.
• DynamicImport-Package – A dynamic import definition is unmodified.
A bundle manifest which mixes legacy syntax with bundle manifest
version 2 syntax is in error and must cause the containing bundle to
fail to install. The specification-version attribute is a deprecated
synonym for the version attribute in bundle manifest version 2 headers.
如果bundles的頭Bundle-ManifestVersion的值不是2或比2大,它必須按照版本3中定義的頭??蚣鼙仨殞姹?中的頭映射為版本4中合適的頭:
• Import-Package –一個(gè)引入定義必須修改規(guī)范版本屬性為版本屬性。不含規(guī)范屬性的引入定義不需要做任何修改,因?yàn)榘姹?中的默認(rèn)值也是0.0.0
• Export-Package –
一個(gè)輸出定義必須修改規(guī)范版本屬性為版本屬性。輸出定義必須附加指令uses。uses指令必須包含所有為這個(gè)給定的bundle引入的和輸出的
packages。另外,如果package沒(méi)有引入定義,那么必須為它添加一個(gè)含有給定版本的引入定義。
• DynamicImport-Package – 動(dòng)態(tài)引入定義沒(méi)有變化。
一個(gè)bundle的manifest包含了多個(gè)版本的混合語(yǔ)法是錯(cuò)誤的,并且必須是這個(gè)bundle的安裝失敗。在版本2的headers中,屬性specification-version是deprecated的,應(yīng)該使用version來(lái)代替它。
3.6 Constraint Solving
The OSGi Framework package resolver provides a number of mechanisms
to match imports to exports. The following sections describe these
mechanisms in detail.
框架的包解析者必須提供一些機(jī)制來(lái)將引入匹配到輸出。以下章節(jié)描述了這些機(jī)制的細(xì)節(jié)。
3.6.1 Diagrams and Syntax
Wires create a graph of nodes. Both the wires as well as nodes
(bundles) carry a significant amount of information. In the next
sections, the following conventions are used to explain the many
details.
Bundles are named A, B, C,... That is, uppercase characters starting
from the character A. Packages are named p, q, r, s, t,... In other
words, lower case characters starting from p. If a version is
important, it is indicated with a dash followed by the version: q-1.0.
The syntax A.p means the package definition (either import or export)
of package p by bundle A.
Import definitions are graphically shown by a white box. Export
definitions are displayed with a black box. Packages that are not
exported or imported are called private packages. They are indicated
with diagonal lines.
Bundles are a set of connected boxes. Constraints are written on the wires,
which are represented by lines.
這段是對(duì)Figure 3.11中的定義進(jìn)行描述。

For example:
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
Figure 3.12 shows the same setup graphically.

3.6.2 Version Matching
Version constraints are a mechanism whereby an import definition can
declare a precise version or a version range for matching an export
definition.
Version ranges encode the assumptions about compatibility. This
specification does not define any compatibility policy; the policy
decision is left to the importer that specifies a version range. A
version range embeds such a policy.
However, the most common version compatibility policies are:
• major – An incompatible update
• minor – A backward compatible update
• micro – A change that does not affect the interface: for example, a bug fix
An import definition must specify a version range as the value for
its version attribute, and the exporter must specify a version as the
value for its version attribute. Matching is done with the rules for
version range matches as described in Version Ranges on page 28.
For example, the following import and export definition resolve
correctly because the version range in the import definition matches
the version in the export definition:
A: Import-Package: p; version="[1,2)"
B: Export-Package: p; version=1.5.1
Figure 3.13 graphically shows how a constraint can exclude an exporter.
版本約束是一個(gè)機(jī)制,通過(guò)它,一個(gè)引入定義可以聲明一個(gè)準(zhǔn)確的版本號(hào)或版本范圍來(lái)匹配一個(gè)輸出定義。
版本范圍將兼容性通過(guò)編碼假設(shè)出來(lái)。本規(guī)范沒(méi)有定義任何兼容性策略;這個(gè)策略留給指定版本范圍的引入者,一個(gè)版本范圍包含下列策略:
• major - 不兼容更新(理解為,如果這個(gè)值被修改,則與其他版本不兼容,例如2.0是不兼容1.9的)
• minor – 向下兼容更新 (例如 1.3是兼容1.2的)
• micro – 不影響接口的改變,例如一個(gè)BUG的修正
一個(gè)引入定義必須指定一個(gè)(引入)版本范圍,就像屬性version一樣,并且輸出者必須指定一個(gè)(輸出)版本就像它的version屬性一樣。匹配是通過(guò)28頁(yè)關(guān)于版本范圍中描述的版本范圍匹配的規(guī)則來(lái)完成的。
例如,以下引入和輸出定義可以正確解析,因?yàn)橐攵x中的版本范圍匹配輸出定義中的版本范圍:
A: Import-Package: p; version="[1,2)"
B: Export-Package: p; version=1.5.1

3.6.3 Optional Packages
A bundle can indicate that it does not require a package to resolve
correctly, but it may use the package if it is available. For example,
logging is important, but the absence of a log service should not
prevent a bundle from running.
Optional imports can be specified in the following ways:
• Dynamic Imports – The DynamicImport-Package header is intended to
look for an exported package when that package is needed. The key use
case for dynamic import is the Class forName method when a bundle does
not know in advance the class name it may be requested to load.
• Resolution Directive – The resolution directive on an import
definition specifying the value optional. A bundle may successfully
resolve if a suitable optional package is not present.
一個(gè)bundle能指明他不需要一個(gè)包來(lái)正確解析,但是如果這個(gè)包可用那么它可能會(huì)用到這個(gè)包。例如,logging是很重要的包,但是即使沒(méi)有它也不會(huì)妨礙這個(gè)bundle運(yùn)行。
可以通過(guò)以下方式指定可選引入:
• Dynamic Imports –頭DynamicImport-Package是指需要的時(shí)候查找一個(gè)輸出包,動(dòng)態(tài)引入最典型的例子是Class的forName方法,一個(gè)bundle沒(méi)有預(yù)先知道一個(gè)可能需要被加載的類(lèi)。
• Resolution Directive – 指令resolution,一個(gè)引入定義指定值optional。如果沒(méi)有給出一個(gè)合適的可選包那么一個(gè)bundle可能解析成功。
The key difference between these two mechanisms is when the wires
are made. An attempt is made to establish a wire for a dynamic import
every time there is an attempt to load a class in that package, whereas
the wire for a resolution optional package may only be established when
the bundle is resolved.
The resolution directive of the import definition can take the value mandatory or optional.
• mandatory – (Default) Indicates that the package must be wired for the bundle to resolve.
• optional – Indicates that the importing bundle may resolve without the package being wired.
The following example will resolve even though bundle B does not
provide the correct version (the package will not be available to the
code when bundle A is resolved).
A: Import-Package: p; resolution:=optional; version=1.6
B: Export-Package: p; q; version=1.5.0
這兩個(gè)機(jī)制的關(guān)鍵區(qū)別是當(dāng)連接生成的時(shí)候。嘗試為每一次動(dòng)態(tài)引入創(chuàng)建一個(gè)連接,并嘗試加載包中的類(lèi),相反僅當(dāng)bundle被解析之后,才可能會(huì)為resolution optional包創(chuàng)建連接。
引入定義的指令resolution可以被賦值mandatory或optional。
• mandatory –表示解析包的時(shí)候包必須被連接(默認(rèn)值)。
• optional – 表示引入bundle可能被解析而不需要連接包。
下面這個(gè)例子會(huì)解析bundle A,即使bundle沒(méi)有提供匹配的版本
A: Import-Package: p; resolution:=optional; version=1.6
B: Export-Package: p; q; version=1.5.0

The implementation of a bundle that uses optional packages must be prepared
to handle the fact that the packages may not be available: that is, an
exception can be thrown when there is a reference to a class from a missing
package.
使用可選包的bundle的實(shí)現(xiàn)必須處理包可能不可用的情況,也就是說(shuō),當(dāng)引用一個(gè)不存在包的時(shí)候能拋出一個(gè)exception。
3.6.4 Package Constraints
Classes can depend on classes in other packages. For example, when they
extend classes from another package, or these other classes appear in
method signatures. It can therefore be said that a package uses other
packages.
These inter-package dependencies are modeled with the uses directive on the Export-Package header.
For example, org.osgi.service.http depends on the package javax.servlet
because it is used in the API. The export definition of the
org.osgi.service.http must therefore contain the uses directive with
the javax.servlet package as its value.
Class space consistency can only be ensured if a bundle has only one exporter for each package.
For example, the Http Service implementation requires servlets to
extend the javax.servlet.http.HttpServlet base class. If the Http
Service bundle would import version 2.4 and the client bundle would
import version 2.1 then a class cast is bound to happen. This is
depicted in Figure 3.15.
類(lèi)可以依賴其他包中的類(lèi)。例如,當(dāng)它們擴(kuò)展其他包中的類(lèi),或其他包中的類(lèi)做為屬性存在時(shí)。因此可以說(shuō)成是一個(gè)包引用其他包。
內(nèi)部包的依賴關(guān)系模擬在頭Export-Package中使用指令uses。
例如,org.osgi.service.http依賴包javax.servlet,因?yàn)橐褂盟腁PI,所以org.osgi.service.http的輸出定義必須包含值為javax.servlet的uses指令。
如果一個(gè)bundle對(duì)每個(gè)包只有一個(gè)輸出者,
Class space consistency僅僅只能被確定。例如,Http
Service實(shí)現(xiàn)需要servlets繼承基類(lèi)javax.servlet.http.HttpServlet,如果Http Service
bundle要引入版本2.4,client bundle 要引入版本2.1,那么一定要產(chǎn)生類(lèi)型轉(zhuǎn)換。

If a bundle imports a package from an exporter then the export
definition of that package can imply constraints on a number of other
packages through the uses directive. The uses directive lists the
packages that the exporter depends upon and therefore constrains the
resolver for imports. These constraints ensure that a set of bundles
share the same class loader for the same package.
如果一個(gè)bundle從一個(gè)輸出者那引入一個(gè)包,那么那個(gè)包的輸出定義就意味著通過(guò)uses指令在其他包上加上了約束。uses指令列出了輸出者依賴的包,因此約束了解析者的引入。這些約束確保了一系列的bundle為同一個(gè)包共享同一個(gè)classloader。
When an importer imports a package with implied constraints, the
resolver must wire the import to the exporter implied by the
constraint. This exporter may in turn imply additional constraints, and
so on. The act of wiring a single import of a package to an exporter
can therefore imply a large set of constraints. The term implied
package constraints refers to the complete set of constraints
constructed from recursively traversing the wires. Implied package
constraints are not automatic imports; rather, implied package
constraints only constrain how an import definition must be resolved.
For example, in Figure 3.16, bundle A imports package p. Assume this
import definition is wired to bundle B. Due to the uses directive (the
ellipse symbols indicates the uses directive) this implies a constraint
on package q.
Further, assuming that the import for package q is wired to bundle C,
then this implies a constraint on the import of package r and s.
Continuing, assuming C.s and C.r are wired to bundle D and E
respectively. These bundles both add package t to the set of implied
packages for bundle A.
當(dāng)一個(gè)引入者以implied約束引入一個(gè)包時(shí),解析者必須通過(guò)約束暗指連接這個(gè)引入到輸出者。這個(gè)輸出者可能會(huì)依次暗示附加約束,等等。因此連接一個(gè)單
一的包的引入到一個(gè)輸出者的動(dòng)作能暗指很多約束。術(shù)語(yǔ)implied package
constraints引用了一系列通過(guò)遞歸完成連接構(gòu)造而來(lái)的約束。它不會(huì)自動(dòng)引入,相反,它僅僅只是約束了一個(gè)引入定義如何被解析。
例如,圖3.16,bundle A引入包p。假設(shè)這個(gè)引入定義被連接到bundle B。由于使用了uses指令(橢圓形標(biāo)記表示使用uses指令),這就暗指一個(gè)約束到包q。
然后,假設(shè)對(duì)包q的引入被連接到bundle C,那么這就暗指了一個(gè)約束到對(duì)包r和s的引入。接著,假如bundle C的包s和r分別被連接到bundle D和E。這些bundle都將包t加入用于bundle A的暗指包中

To maintain class space consistency, the Framework must ensure that
none of its bundle imports conflicts with any of that bundle’s implied
packages.
For the example, this means that the Framework must ensure that the
import definition of A.t is wired to package D.t. Wiring this import
definition to package F.t violates the class space consistency. This
violation occurs because bundle A could be confronted with objects with
the same class name but from the class loaders of bundle D and F. This
would potentially create ClassCastExceptions. Alternatively, if all
bundles are wired to F.t, then the problem also goes away.
Another scenario with this case is depicted in Figure 3.15. Bundle A
imports the Http Service classes from bundle B. Bundle B has grouped
the org.osgi.service.http and the javax.servlet and bundle A is
therefore constrained to wire javax.servlet to the same exporter as
bundle B.
As an example of a situation where the uses directive makes resolving
impossible consider the following setup that is correctly resolved:
為了維護(hù)類(lèi)空間的連貫性,框架必須確保bundle的引入不會(huì)與bundle的暗指包發(fā)生沖突。
例如,框架必須確保A.t的引入定義是連接到包D.t的。將這個(gè)引入定義連接到包F.t會(huì)破壞類(lèi)空間的連貫性。
因?yàn)閎undle A能得到相同類(lèi)名的對(duì)象,但是確是從bundle D和F的class loader得到的,這就潛藏著ClassCastExceptions。作為另一種方案,如果所有的bundles都連接到F.t,就不會(huì)存在這個(gè)問(wèn)題了。
這個(gè)案例的另外一種情況描述于圖3.15. bundle A從B那引入類(lèi)Http Service。bundle
B又包含org.osgi.service.http和javax.servlet,因此bundle
A約束javax.servlet連接到像連接bundle B一樣的輸出者。
做為一個(gè)不可能使用uses指令解析的例子,考慮以下可以被正確解析的設(shè)置 :
A: Import-Package: q; version="[1.0,1.0]"
Export-Package: p; uses:="q,r"
B: Export-Package: q; version=1.0
C: Export-Package: q; version=2.0
These specific constraints can be resolved because the import A.q can
be wired to the export B.q but not C.q due to the version constraint.
Adding a bundle D will now not be possible:
這個(gè)特殊的約束可以被解析,因?yàn)榘姹炯s束使A.q的引入能被連接到B.q的輸出,而不是C.q。
如果再增加一個(gè)bundle D則不行:
D: Import-Package: p, q; version=2.0
Package D.p must be wired to package A.p because bundle A is the only
exporter. However, this implies the use of package q due the uses
directive in the package A.q import. Package A.q is wired to B.q-1.0.
However, import package D.q requires version 2.0 and can therefore not
be resolved without violating the class space constraint.
包D.p必須被連接到包A.p,因?yàn)閎undle A是唯一一個(gè)輸出者,可是,這就意味著在包A.q的引入中,包q的使用是由于uses指令。包A.q被連接到B.q-1.0.然而包D.q需要版本2.0,因此它由于類(lèi)空間約束而不能被解析。
This scenario is depicted in Figure 3.17.
3.6.5 Attribute Matching
Attribute matching is a generic mechanism to allow the importer and
exporter to influence the matching process in a declarative way. In
order for an import definition to be resolved to an export definition,
the values of the attributes specified by the import definition must
match the values of the attributes of the export definition. By
default, a match is not prevented if the export definition contains
attributes that do not occur in the import definition.
The mandatory directive in the export definition can reverse this by
listing all attributes that the Framework must match in the import
definition.
Any information specified in the DynamicImport-Package is ignored during the resolve phase.
屬性匹配是一個(gè)常見(jiàn)的機(jī)制,允許引入者和輸出者以聲明的方式影響匹配過(guò)程。為了使一個(gè)引入定義被解析到一個(gè)輸出定義,引入定義指定的屬性的值必須匹配輸出
定義的屬性的值。默認(rèn)情況下,輸出定義包含的屬性可以不必出現(xiàn)在引入定義中。相反,輸出定義中的指令mandatory
列出的所有屬性,框架必須將其與引入定義的屬性匹配。
For example, the following statements will match.
A: Import-Package: com.acme.foo;company=ACME
B: Export-Package: com.acme.foo;
company="ACME";
security=false
Attribute values are compared string wise except for the version and
bundle- version attributes which use version range comparisons.
3.6.6 Mandatory Attributes
There are two types of attributes: mandatory and optional. Mandatory
attributes must be specified in the import definition to match.
Optional attributes are ignored when they are not referenced by the
importer.Attributes are optional by default.
The exporter can specify mandatory attributes with the mandatory
directive in the export definition. This directive contains a
comma-separated list of attribute names that must be specified by the
importer to match.
For example, the following import definition must not match the export definition because security is a mandatory attribute:
這有兩種屬性類(lèi)型:mandatory和optional。Mandatory屬性必須在引入定義中指定用于匹配輸出定義。Optional屬性當(dāng)引入者沒(méi)有引用的時(shí)候被忽略。默認(rèn)情況下屬性是可選的。
輸出者可以在輸出定義中通過(guò)mandatory 指令來(lái)指定強(qiáng)制屬性。這個(gè)指令包含了以逗號(hào)隔開(kāi)的屬性名的列表,它們必須被引入者指定用于匹配。
例如,下面的引入定義不能匹配輸出定義,因?yàn)閟ecurity是強(qiáng)制屬性
A: Import-Package: com.acme.foo;company=ACME
B: Export-Package: com.acme.foo;
company="ACME";
security=false;
mandatory:=security
3.6.7 Class Filtering
An exporter can limit the visibility of the classes in a package with
the include and exclude directives on the export definition. The value
of each of these directives is a comma-separated list of class names.
Note that the use of a comma in the value requires it to be enclosed in
double quotes.
Class names must not include their package name and do not end with
.class. That is, the class com.acme.foo.Daffy is named Daffy in either
list. The class name can include multiple wildcards (’*’).
The default for the include directive is’*’ (wildcard matching all
names), and for the exclude directive, so that no classes or resources
are excluded, an empty list that matches no names. If include or
exclude directive are specified, the corresponding default is
overridden.
A class is only visible if it is:
• Matched with an entry in the included list, and
• Not matched with an entry in the excluded list.
一個(gè)輸出者能在輸出定義中通過(guò)include和exclude指令限制一個(gè)包中的類(lèi)的可見(jiàn)性。這兩個(gè)指令的值都是以逗號(hào)分隔的類(lèi)名列表。注意值中逗號(hào)的使用,它需要被雙引號(hào)括起來(lái)。
類(lèi)名必須包含他們的包名并且不以.class結(jié)尾。也就是說(shuō),com.acme.foo.Daffy是是其中一個(gè)列表中名為Daffy的對(duì)象。類(lèi)名也可以包含多個(gè)通配符('*')。
include指令的默認(rèn)值是'*',對(duì)于exclude指令來(lái)說(shuō)是空列表,匹配空名,因此沒(méi)有類(lèi)或資源被拒絕。如果yinclude或exclude指令被指定,相應(yīng)的默認(rèn)值要被重載。
一個(gè)類(lèi)僅僅只能因下列因素而可見(jiàn):
• 匹配include列表中的實(shí)體,并且
• 不匹配exclude列表中的實(shí)體
In all other cases, loading or finding fails, and a Class Not Found
Exception is thrown for a class load. The ordering of include and
exclude is not significant.
The following example shows an export statement, and a list of files with their visibility status.
否則,加載或?qū)ふ沂。⑶覓伋鯟lassNotFoundException。include和exclude的順序沒(méi)有特殊要求。
下面這個(gè)例子顯示了一個(gè)輸出聲明,和一個(gè)文件列表以及它們的可見(jiàn)性狀態(tài)。
Export-Package: com.acme.foo;
include:="Qux*,BarImpl";
exclude:=QuxImpl
com/acme/foo
QuxFoo visible
QuxBar visible
QuxImpl excluded
BarImpl visible
Care must be taken when using filters. For example, a new version of a
module that is intended to be backward compatible with an earlier
version should not filter out classes or resources that were not
filtered out by the earlier version. In addition, when modularizing
existing code, filtering out classes or resources from an exported
package may break users of the package.
For example, packages defined by standard bodies often require an
implementation class in the standardized package to have package access
to the specification classes.
使用過(guò)濾器的時(shí)候必須注意,例如,一個(gè)具有向下兼容的新版本模塊,不應(yīng)該過(guò)濾掉那些沒(méi)有被前面的版本過(guò)濾掉的類(lèi)或資源。另外,將現(xiàn)有代碼模塊化,從一個(gè)輸出包中過(guò)濾類(lèi)或資源可能會(huì)打斷包的使用者。
例如,標(biāo)準(zhǔn)結(jié)構(gòu)定義的包經(jīng)常會(huì)需要一個(gè)標(biāo)準(zhǔn)包中的實(shí)現(xiàn)類(lèi),用于訪問(wèn)規(guī)范類(lèi)。
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;
}
}
The Implementation class must not be available to external bundles
because it allows the implementation to be set. By excluding the
Implementation class, only the exporting bundle can see this class. The
export definition for this header could look like:
類(lèi)Implementation必須對(duì)外部bundles不可用,因?yàn)樗试Simplementation被設(shè)置。通過(guò)拒絕類(lèi)Implementation,僅僅只有輸出bundle能看見(jiàn)它,輸出定義可以這樣:
Export-Package: org.acme.open; exclude:=Implementation
3.6.8 Provider Selection
Provider selection allows the importer to select which bundles can be
considered as exporters. Provider selection is used when there is no
specification contract between the importer and the exporter. The
importer tightly couples itself to a specific exporter, typically the
bundle that was used for testing. To make the wiring less brittle, the
importer can optionally specify a
range of bundle versions that will match.
An importer can select an exporter with the import attributes
bundlesymbolic- name and bundle-version. The Framework automatically
provides these attributes for each export definition. These attributes
must not be specified in an export definition.
The export definition bundle-symbolic-name attribute will contain the
bundle symbolic name as specified in the Bundle-SymbolicName header
without any parameters. The export definition bundle-version attribute
is set to the value of the Bundle-Version header or its default of
0.0.0 when absent.
The bundle-symbolic-name is matched as an attribute. The bundle-version
attribute is matched using the version range rules as defined in
Version Ranges on page 28. The import definition must be a version
range and the export definition is a version.
For example, the following definitions will match:
Provider selection允許引入者選擇哪個(gè)bundle可以被認(rèn)為是輸出者。
Provider selection用于當(dāng)引入者與輸出者之間沒(méi)有規(guī)范約定的時(shí)候。引入者嚴(yán)密的將自己連接到指定的輸出者,特別是在測(cè)試的時(shí)候。為了放寬連接,引入者能指定一個(gè)bundle版本的范圍來(lái)匹配。
引入者能通過(guò)屬性bundle-symbolic- name和bundle-version選擇一個(gè)輸出者??蚣茏詣?dòng)為每一個(gè)輸出定義提供這些屬性。但是這些屬性必須不能被指定在輸出定義中。
輸出定義bundle-symbolic-name屬性將包含不含其它參數(shù),指定在頭Bundle-SymbolicName中的bundle標(biāo)記名。輸出定義bundle-version是頭Bundle-Version的值或默認(rèn)值0.0.0
bundle-symbolic-name作為一個(gè)屬性被匹配,bundle-version使用版本范圍規(guī)則來(lái)匹配。引入定義必須是一個(gè)版本范圍,輸出定義必須是一個(gè)版本值。
例如,下面的定義會(huì)被匹配:
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
The following statements will not match because B does not specify a version and thus defaults to 0.0.0:
下面的聲明不會(huì)被匹配,因?yàn)锽沒(méi)有指定版本,而是使用默認(rèn)值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
Selecting an exporter by symbolic name can result in brittleness
because of hard coupling of the package to the bundle. For example, if
the exporter eventually needs to be refactored into multiple separate
bundles, all importers must be changed. Other arbitrary matching
attributes do not have this disadvantage as they can be specified
independently of the exporting bundle.
The brittleness problem of the bundle symbolic name in bundle
refactoring can be partly overcome by writing a facade bundle using the
same bundle symbolic name as the original bundle.
通過(guò)標(biāo)記名來(lái)選擇一個(gè)輸出者會(huì)得到一個(gè)比較模糊的結(jié)果,因?yàn)閷?duì)于bundle來(lái)說(shuō)是硬連接。例如,如果一個(gè)輸出者最終需要被重構(gòu)成多個(gè)bundles,所有的引入者必須被修改。其他專有匹配屬性就沒(méi)有這個(gè)缺點(diǎn),因?yàn)樗鼈兡鼙华?dú)立指定到輸出bundle。
在重構(gòu)中,bundle標(biāo)記名的模糊問(wèn)題,可以通過(guò)寫(xiě)一個(gè)具有相同標(biāo)記名的門(mén)戶bundle作為原先的那個(gè)bundle來(lái)分成幾塊解決。
轉(zhuǎn)自:http://www.tkk7.com/Phrancol/articles/189711.html