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.
標準的JAVA平臺對打包,部署和驗證基于JAVA的應用程序和組件僅僅提供了有限的支持。所以許多基于JAVA的項目,例如JBoss和
NetBeans,都通過編寫自己的類加載器生成面向模塊的層來打包,部署和驗證應用程序和組件。OSGi框架為java模塊化提供了一個通用的標準的解
決方案。
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。一個bundle由java類和資源組成,它們能給終端用戶使用。在具備良好定義的前提下,導出bundle與引入bundle之間能共享java package。
在OSGi平臺,bundle是用于部署基于java應用程序的唯一實體。
一個bundle被部署為一個JAR文件,JAR文件是一個標準的ZIP格式文件用于保存應程序和資源。
一個bundle文件:
• 包含提供某些功能所需的必要資源。這些資源可能是JAVA類文件,也可能是HTML文件,幫助文件,圖標等其他文件。一個bundle jar文件中也能嵌入其他的JAR文件作為資源和類文件,當然這不能是一個循環嵌套。
•
包含一個manifest文件,用于描述JAR文件的內容和提供與bundle相關的信息。manifest文件使用頭的形式來指定OSGi框架能正確安
裝和激活bundle所需的信息。例如,它聲明了諸如java包這樣的所依賴的資源,這些java包在bundle運行之前必須對它是可用的。
• 能在OSGI-OPT目錄或其子目錄中包含可選文檔,所有在這個目錄中的信息都是可選的。例如OSGI-OPT目錄可用來存放bundle的源代碼。不過OSGi平臺管理系統可能會刪除這些信息用于保存存儲空間
一個bundle一旦被啟動,它將給其他已經安裝在平臺中的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.
一個bundle可以在manifest文件中攜帶與它自己有關的描述信息,這個文件被包含在bundle jar文件中META-INF目錄中名為MANIFEST.MF。
OSGi框架定義的諸如Export-Package 和Bundle-Classpath 的manifest頭是bundle開發者用來提供與bundle有關的描述信息,Manifest頭必須嚴格按照[28]manifest Format中定義的規則。
一個實現框架必須:
• 處理manifest的主片段。manifest中的每一個片段僅僅在bundle的簽名驗證的過程中使用。
• 忽略為被定義的頭。bundle開發者能根據需要定義額外的頭。
• 忽略未知屬性和標識
所有被指定的頭都被列在下面的內容中。如非特殊說明,所有頭都是可選的。
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.
框架啟動時如何激活這個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.
啟動和停止bundle的類名
3.2.1.3 Bundle-Category: osgi, test, nursery
The Bundle-Category header holds a comma-separated list of category names.
bundle的類別
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.
定義了以逗號分隔的jar文件路徑或bundle中包含類和資源的目錄的列表。點表示bundle jar的根目錄,它也是默認路徑。
3.2.1.5 Bundle-ContactAddress: 2400 Oswego Road, Austin, TX 74563
The Bundle-ContactAddress header provides the contact address of the vendor.
bundle提供者的聯系方式
3.2.1.6 Bundle-Copyright: OSGi (c) 2002
The Bundle-Copyright header contains the copyright specification for this bundle.
bundle提供者的版權說明
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.
包含了一個在bundle中可以找到本地化文件的路徑。默認值是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所遵循的規范的版本號,這個頭決定了bundle是否遵循這個規范的規則。
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 定義了一個可讀取得名字,它應該是個較短的,易識別的名字,可以包含空格。
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的可被執行環境
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指定了一個唯一的,非本地化的名字,這個名字應該反轉于域名結構。這個頭必須被指定
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的版本,默認值是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.
包含了一個以逗號分隔的包名的列表,列表中的包應該在需要的時候被動態引入
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
為這個片段定義一個主機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.
為這個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能在同一個虛擬機中,在這個虛擬機中,bundles能對其他bundles隱藏包和類,也能對其他bundles共享包和類。
隱藏和共享包的關鍵是java class loader通過良好定義規則從bundle空間的子集(子class
loader)中加載類。每一個bundle都有一個class loader,這個class loader與其他bundles的class
loader形成了一個類加載委派網絡,如圖

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能夠從以下位置加載類和資源:
• boot類路徑 - boot類路徑包含了java.*的包和它們的實現包(可以理解為應用服務器的類路徑)
• 框架類路徑 - 通常框架會有不同的class loader 去加載框架的實現類,和主服務接口類。
• bundle空間 - bundle空間由與bundle相關聯的jar文件組成,加上其他包含在bundle中的jar文件
那么一個類空間則可以從一個給定的bundle的class loader中獲取。因此,一個給定的bundle的類空間包含的類可以來自以下方面:
• 父class loader(通常是boot類路徑中的java.*包)
• 引入的包
• 所依賴的包
• bundle的類路徑(私有包)
• 附加的片段(例如附加的jar包)
一個類空間必須是consistent(用哪個詞來形容不可包含相同名字的兩個元素?),這樣它不能包含2個具有相同名字的類。不過,相同OSGi平臺中不同的類空間可以包含兩個名字相同的類。模塊化層支持一個類的多個版本被加載在同一個虛擬機中。

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.
因此對于類加載,框架有很多工作要做。在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。解析是將引入者搭配到輸出者的過程,也是滿足約束的過程。這個過程必須在bundle中的代碼被加載或執行之前進行。
搭配,是輸出者與引入者之間的真實連接,一個有效的搭配是滿足了所有約束的鏈接。
3.5 Resolving Metadata
The following sections define the manifest headers that provide the metadata for the resolver.
以下章節定義了為解析者提供元數據的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:
一個bundle的manifest必須在頭Bundle-ManifestVersion中明確表示這個OSGi manifest頭語法的版本號。bundle必須使用這個頭。
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實現框架應該支持不含Bundle-ManifestVersion頭的bundle manifest,并且兼容1.2。
版本2的bundle manifest必須指定bundle標記名,可以不用指定bundle版本,因為版本頭有默認值(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 是一個必須的頭,框架可以使用bundle標記名和版本號來識別bundle的唯一性,也就是說,將給定標記名和版本號的bundle與其他擁有相同標記名(區分大小寫)和精確版本號的bundle進行比較。
當安裝一個與已經存在的bundle具有相同標記名和版本號的bundle時,必須安裝失敗。
一個bundle的標記名是開發者給定的。
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僅僅只能有一個版本被解析。值為true表示一個單例bundle,否則為多例。當具有相同標記名的多個版本的單例bundle被安裝
的時候,框架必須最多只能解析一個bundle。單例bundle的解析不會影響到其他具有相同標記名的非單例bundle。
• fragment-attachment - 定義了片段是如何被附加的,有以下值:
• always - 當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是一個可選的頭,它的默認值是0.0.0。
如果主版本號或三級版本號部分沒有被指定,它們將被設置成默認值0. 如果版本界定給沒有指定(Alpha, Beta等),則為空字符串。
版本號是可對比的。這個比較是通過major, minor, and micro的順序比較它們的數字大小,然后使用String類的compareTo方法來比較版本界定來完成的。
一個版本和另一個版本相同意味著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定義了對共享包的引入的約束。語法如下
Import-Package ::= import ( ',' import )*
import ::= package-names ( ';' parameter )*
package-names ::= package-name( ';' package-name )* // See 1.3.2
這個頭允許很多包被引入。一個引入的定義是對一個bundle的一個包的描述。這個語法允許以分號隔開的多個包名被描述在這個結構中。
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,表示這個包必須被解析,這是默認值。如果一個mandatory包不能被解析,那么這個bundle將解析失敗。值optional表示包是可選的。
開發者可以指定專有匹配屬性:
• version - 一個選擇輸出包版本的版本范圍。語法必須遵循28頁(原規范中的28頁)中版本范圍的語法。如果這個屬性沒有被指定,默認值為[0.0.0, ∞),就是所有版本都可以用。
• specification-version - 這個屬性是version的別名,僅僅只是為了使升級更簡單(從早期版本移植過來)。如果version被指定,這兩個屬性的值必須相等。
• bundle-symbolic-name - 輸出bundle的標記名。在具有片段bundle的例子中,這個值是宿主bundle的標記名。
• bundle-version - 輸出bundle的版本范圍。在具有片段bundle的例子中,這個值是宿主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
為了允許引入一個包,一個bundle必須有PackagePermission[<package-name>, IMPORT]. 當下列情況發生時必須終止安裝或更新bundle:
• 一個指令或屬性出現多次,或
• 多次定義對同一個包的引入
正確定義的列子:
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的語法與Import-Package類似。僅僅只是一些指令和屬性不同
這個頭允許包被輸出。一個輸出的定義是對為一個bundle輸出一個包的描述。這個語法允許將輸出多個包的聲明定義在一個以分號分隔的子句中。對同
一個包的多個輸出定義是允許的,例如,對于不同的引入者,需要使用不同的屬性的時候。(比如2個引入者需要的是2個不同的這個bundle的版本,但是這
個bundle對這2個引入這都可用,那么就以2個版本的形式輸出)
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 - 給輸出包使用的以逗號分隔的包名的列表。注意值中逗號的使用,它需要被雙引號括起來。如果一個輸出包被引入包選中,那么解析者(框架)需要確保引入包引入的是列表中與之版本號相同的包。
• mandatory - 以逗號分隔的屬性名的列表。注意值中逗號的使用,它需要被雙引號括起來。一個引入這個包的bundle必須指定mandatory屬性和一個匹配值,用于解析到輸出包。
• include - 以逗號分隔的必須對引入者可見的類名的列表。
• exclude -以逗號分隔的必須對引入者不可見的類名的列表
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.
以下屬性是這部分規范的一部分:
• version - 以定義在page28中的語法命名的包的版本號。它定義了關聯的包的版本。默認值0.0.0。
• specification-version - 屬性version的別名.
另外,專有匹配屬性可以被指定。框架會自動以下列屬性關聯每一個包的輸出定義(這個屬性只是出現在importer中,用來匹配輸出包,而不能出現在輸出包中):
• bundle-symbolic-name - 輸出bundle的標記名。在含有片段的例子中,是宿主bundle的標記名。
• 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
當出現以下條件時,安裝或更新必須被終止:
• 一個指令或屬性出現多次
• bundle-symbolic-name 或 bundle-version 屬性被指定在 Export-Package 中.
一個輸出定義并非一個自動引入定義。一個輸出了一個包的bundle并不會引入這個包,而是通過bundle
classpath來獲取這個包,這樣一個輸出了的包只能被其他bundles使用,但是輸出bundle不會接受從另外一個bundle而來的這個包的
替代品。(理解為,一個bundle含有package
com.foo,自己需要這個package,也輸出這個package,而一個bundle也同樣輸出這個package,第一個bundle不會使用
第二個bundle中的package,而是通過classpath使用自己的那個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.
輸出一個包并不意味著對這個包的引入(不過在第三版中,輸出意味著引入)。這樣做的原因是使一個bundle為其他bundles提供
package,不需要考慮這個包會被解析者以其他bundle中相同的package替換。這在一個應用程序是由一系列相互引用其實現包的bundle
的例子中是很常見的。
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.
包的替換對于bundles的內部運作能力是很重要的。在java,bundles的內部操作僅僅只能當它們為相同的classes使用相同的
class
loader才能進行。因此,2個bundles,輸出了相同的package,但是不能引入它,不能從它那獲取共享對象。這對像Service
Layer這樣的協作機制來說是很重要的。Bundles僅僅只能使用相同的service對象,如果他們的類和接口來自相同的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應該引入輸出的packages,允許解析者替換那些包含了接口和其他共享對象的packages。這個替換允許bundles通過service注冊和其他機制來進行內部操作。另外,這個引入應該被盡可能不受限制而是解析者獲得最大的靈活性。
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中定義的頭。框架必須將版本3中的頭映射為版本4中合適的頭:
• 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.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.
框架的包解析者必須提供一些機制來將引入匹配到輸出。以下章節描述了這些機制的細節。
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.
這段是對Figure 3.11中的定義進行描述。

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.
版本約束是一個機制,通過它,一個引入定義可以聲明一個準確的版本號或版本范圍來匹配一個輸出定義。
版本范圍將兼容性通過編碼假設出來。本規范沒有定義任何兼容性策略;這個策略留給指定版本范圍的引入者,一個版本范圍包含下列策略:
• major - 不兼容更新(理解為,如果這個值被修改,則與其他版本不兼容,例如2.0是不兼容1.9的)
• minor – 向下兼容更新 (例如 1.3是兼容1.2的)
• micro – 不影響接口的改變,例如一個BUG的修正
一個引入定義必須指定一個(引入)版本范圍,就像屬性version一樣,并且輸出者必須指定一個(輸出)版本就像它的version屬性一樣。匹配是通過28頁關于版本范圍中描述的版本范圍匹配的規則來完成的。
例如,以下引入和輸出定義可以正確解析,因為引入定義中的版本范圍匹配輸出定義中的版本范圍:
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.
一個bundle能指明他不需要一個包來正確解析,但是如果這個包可用那么它可能會用到這個包。例如,logging是很重要的包,但是即使沒有它也不會妨礙這個bundle運行。
可以通過以下方式指定可選引入:
• Dynamic Imports –頭DynamicImport-Package是指需要的時候查找一個輸出包,動態引入最典型的例子是Class的forName方法,一個bundle沒有預先知道一個可能需要被加載的類。
• Resolution Directive – 指令resolution,一個引入定義指定值optional。如果沒有給出一個合適的可選包那么一個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
這兩個機制的關鍵區別是當連接生成的時候。嘗試為每一次動態引入創建一個連接,并嘗試加載包中的類,相反僅當bundle被解析之后,才可能會為resolution optional包創建連接。
引入定義的指令resolution可以被賦值mandatory或optional。
• mandatory –表示解析包的時候包必須被連接(默認值)。
• optional – 表示引入bundle可能被解析而不需要連接包。
下面這個例子會解析bundle A,即使bundle沒有提供匹配的版本
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的實現必須處理包可能不可用的情況,也就是說,當引用一個不存在包的時候能拋出一個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.
類可以依賴其他包中的類。例如,當它們擴展其他包中的類,或其他包中的類做為屬性存在時。因此可以說成是一個包引用其他包。
內部包的依賴關系模擬在頭Export-Package中使用指令uses。
例如,org.osgi.service.http依賴包javax.servlet,因為要使用它的API,所以org.osgi.service.http的輸出定義必須包含值為javax.servlet的uses指令。
如果一個bundle對每個包只有一個輸出者,
Class space consistency僅僅只能被確定。例如,Http
Service實現需要servlets繼承基類javax.servlet.http.HttpServlet,如果Http Service
bundle要引入版本2.4,client bundle 要引入版本2.1,那么一定要產生類型轉換。

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.
如果一個bundle從一個輸出者那引入一個包,那么那個包的輸出定義就意味著通過uses指令在其他包上加上了約束。uses指令列出了輸出者依賴的包,因此約束了解析者的引入。這些約束確保了一系列的bundle為同一個包共享同一個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.
當一個引入者以implied約束引入一個包時,解析者必須通過約束暗指連接這個引入到輸出者。這個輸出者可能會依次暗示附加約束,等等。因此連接一個單
一的包的引入到一個輸出者的動作能暗指很多約束。術語implied package
constraints引用了一系列通過遞歸完成連接構造而來的約束。它不會自動引入,相反,它僅僅只是約束了一個引入定義如何被解析。
例如,圖3.16,bundle A引入包p。假設這個引入定義被連接到bundle B。由于使用了uses指令(橢圓形標記表示使用uses指令),這就暗指一個約束到包q。
然后,假設對包q的引入被連接到bundle C,那么這就暗指了一個約束到對包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:
為了維護類空間的連貫性,框架必須確保bundle的引入不會與bundle的暗指包發生沖突。
例如,框架必須確保A.t的引入定義是連接到包D.t的。將這個引入定義連接到包F.t會破壞類空間的連貫性。
因為bundle A能得到相同類名的對象,但是確是從bundle D和F的class loader得到的,這就潛藏著ClassCastExceptions。作為另一種方案,如果所有的bundles都連接到F.t,就不會存在這個問題了。
這個案例的另外一種情況描述于圖3.15. bundle A從B那引入類Http Service。bundle
B又包含org.osgi.service.http和javax.servlet,因此bundle
A約束javax.servlet連接到像連接bundle B一樣的輸出者。
做為一個不可能使用uses指令解析的例子,考慮以下可以被正確解析的設置 :
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:
這個特殊的約束可以被解析,因為版本約束使A.q的引入能被連接到B.q的輸出,而不是C.q。
如果再增加一個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,因為bundle A是唯一一個輸出者,可是,這就意味著在包A.q的引入中,包q的使用是由于uses指令。包A.q被連接到B.q-1.0.然而包D.q需要版本2.0,因此它由于類空間約束而不能被解析。
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.
屬性匹配是一個常見的機制,允許引入者和輸出者以聲明的方式影響匹配過程。為了使一個引入定義被解析到一個輸出定義,引入定義指定的屬性的值必須匹配輸出
定義的屬性的值。默認情況下,輸出定義包含的屬性可以不必出現在引入定義中。相反,輸出定義中的指令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:
這有兩種屬性類型:mandatory和optional。Mandatory屬性必須在引入定義中指定用于匹配輸出定義。Optional屬性當引入者沒有引用的時候被忽略。默認情況下屬性是可選的。
輸出者可以在輸出定義中通過mandatory 指令來指定強制屬性。這個指令包含了以逗號隔開的屬性名的列表,它們必須被引入者指定用于匹配。
例如,下面的引入定義不能匹配輸出定義,因為security是強制屬性
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.
一個輸出者能在輸出定義中通過include和exclude指令限制一個包中的類的可見性。這兩個指令的值都是以逗號分隔的類名列表。注意值中逗號的使用,它需要被雙引號括起來。
類名必須包含他們的包名并且不以.class結尾。也就是說,com.acme.foo.Daffy是是其中一個列表中名為Daffy的對象。類名也可以包含多個通配符('*')。
include指令的默認值是'*',對于exclude指令來說是空列表,匹配空名,因此沒有類或資源被拒絕。如果yinclude或exclude指令被指定,相應的默認值要被重載。
一個類僅僅只能因下列因素而可見:
• 匹配include列表中的實體,并且
• 不匹配exclude列表中的實體
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.
否則,加載或尋找失敗,并且拋出ClassNotFoundException。include和exclude的順序沒有特殊要求。
下面這個例子顯示了一個輸出聲明,和一個文件列表以及它們的可見性狀態。
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.
使用過濾器的時候必須注意,例如,一個具有向下兼容的新版本模塊,不應該過濾掉那些沒有被前面的版本過濾掉的類或資源。另外,將現有代碼模塊化,從一個輸出包中過濾類或資源可能會打斷包的使用者。
例如,標準結構定義的包經常會需要一個標準包中的實現類,用于訪問規范類。
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:
類Implementation必須對外部bundles不可用,因為它允許implementation被設置。通過拒絕類Implementation,僅僅只有輸出bundle能看見它,輸出定義可以這樣:
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允許引入者選擇哪個bundle可以被認為是輸出者。
Provider selection用于當引入者與輸出者之間沒有規范約定的時候。引入者嚴密的將自己連接到指定的輸出者,特別是在測試的時候。為了放寬連接,引入者能指定一個bundle版本的范圍來匹配。
引入者能通過屬性bundle-symbolic- name和bundle-version選擇一個輸出者。框架自動為每一個輸出定義提供這些屬性。但是這些屬性必須不能被指定在輸出定義中。
輸出定義bundle-symbolic-name屬性將包含不含其它參數,指定在頭Bundle-SymbolicName中的bundle標記名。輸出定義bundle-version是頭Bundle-Version的值或默認值0.0.0
bundle-symbolic-name作為一個屬性被匹配,bundle-version使用版本范圍規則來匹配。引入定義必須是一個版本范圍,輸出定義必須是一個版本值。
例如,下面的定義會被匹配:
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:
下面的聲明不會被匹配,因為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
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.
通過標記名來選擇一個輸出者會得到一個比較模糊的結果,因為對于bundle來說是硬連接。例如,如果一個輸出者最終需要被重構成多個bundles,所有的引入者必須被修改。其他專有匹配屬性就沒有這個缺點,因為它們能被獨立指定到輸出bundle。
在重構中,bundle標記名的模糊問題,可以通過寫一個具有相同標記名的門戶bundle作為原先的那個bundle來分成幾塊解決。
轉自:http://www.tkk7.com/Phrancol/articles/189711.html