OSGi Service Platform Core Specification Release 4 - Module Layer [zhuan]
Version 1.43.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平臺對打包,部署和驗(yàn)證基于JAVA的應(yīng)用程序和組件僅僅提供了有限的支持。所以許多基于JAVA的項(xiàng)目,例如JBoss和
NetBeans,都通過編寫自己的類加載器生成面向模塊的層來打包,部署和驗(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類和資源組成,它們能給終端用戶使用。在具備良好定義的前提下,導(dǎo)出bundle與引入bundle之間能共享java package。
在OSGi平臺,bundle是用于部署基于java應(yīng)用程序的唯一實(shí)體。
一個(gè)bundle被部署為一個(gè)JAR文件,JAR文件是一個(gè)標(biāo)準(zhǔn)的ZIP格式文件用于保存應(yīng)程序和資源。
一個(gè)bundle文件:
• 包含提供某些功能所需的必要資源。這些資源可能是JAVA類文件,也可能是HTML文件,幫助文件,圖標(biāo)等其他文件。一個(gè)bundle jar文件中也能嵌入其他的JAR文件作為資源和類文件,當(dāng)然這不能是一個(gè)循環(huán)嵌套。
• 包含一個(gè)manifest文件,用于描述JAR文件的內(nèi)容和提供與bundle相關(guān)的信息。manifest文件使用頭的形式來指定OSGi框架能正確安 裝和激活bundle所需的信息。例如,它聲明了諸如java包這樣的所依賴的資源,這些java包在bundle運(yùn)行之前必須對它是可用的。
• 能在OSGI-OPT目錄或其子目錄中包含可選文檔,所有在這個(gè)目錄中的信息都是可選的。例如OSGI-OPT目錄可用來存放bundle的源代碼。不過OSGi平臺管理系統(tǒng)可能會刪除這些信息用于保存存儲空間
一個(gè)bundle一旦被啟動,它將給其他已經(jīng)安裝在平臺中的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開發(fā)者用來提供與bundle有關(guān)的描述信息,Manifest頭必須嚴(yán)格按照[28]manifest Format中定義的規(guī)則。
一個(gè)實(shí)現(xiàn)框架必須:
• 處理manifest的主片段。manifest中的每一個(gè)片段僅僅在bundle的簽名驗(yàn)證的過程中使用。
• 忽略為被定義的頭。bundle開發(fā)者能根據(jù)需要定義額外的頭。
• 忽略未知屬性和標(biāo)識
所有被指定的頭都被列在下面的內(nèi)容中。如非特殊說明,所有頭都是可選的。
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.
框架啟動時(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.
啟動和停止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中包含類和資源的目錄的列表。點(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)說明
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ī)范的版本號,這個(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è)較短的,易識別的名字,可以包含空格。
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è)頭必須被指定
3.2.1.15 Bundle-UpdateLocation: http://www.acme.com/Firewall/bundle.jar
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è)以逗號分隔的包名的列表,列表中的包應(yīng)該在需要的時(shí)候被動態(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能對其他bundles隱藏包和類,也能對其他bundles共享包和類。
隱藏和共享包的關(guān)鍵是java class loader通過良好定義規(guī)則從bundle空間的子集(子class
loader)中加載類。每一個(gè)bundle都有一個(gè)class loader,這個(gè)class loader與其他bundles的class
loader形成了一個(gè)類加載委派網(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能夠從以下位置加載類和資源:
• boot類路徑 - boot類路徑包含了java.*的包和它們的實(shí)現(xiàn)包(可以理解為應(yīng)用服務(wù)器的類路徑)
• 框架類路徑 - 通常框架會有不同的class loader 去加載框架的實(shí)現(xiàn)類,和主服務(wù)接口類。
• bundle空間 - bundle空間由與bundle相關(guān)聯(lián)的jar文件組成,加上其他包含在bundle中的jar文件
那么一個(gè)類空間則可以從一個(gè)給定的bundle的class loader中獲取。因此,一個(gè)給定的bundle的類空間包含的類可以來自以下方面:
• 父class loader(通常是boot類路徑中的java.*包)
• 引入的包
• 所依賴的包
• bundle的類路徑(私有包)
• 附加的片段(例如附加的jar包)
一個(gè)類空間必須是consistent(用哪個(gè)詞來形容不可包含相同名字的兩個(gè)元素?),這樣它不能包含2個(gè)具有相同名字的類。不過,相同OSGi平臺中不同的類空間可以包含兩個(gè)名字相同的類。模塊化層支持一個(gè)類的多個(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.
因此對于類加載,框架有很多工作要做。在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。解析是將引入者搭配到輸出者的過程,也是滿足約束的過程。這個(gè)過程必須在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頭語法的版本號。bundle必須使用這個(gè)頭。
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)記名和版本號來識別bundle的唯一性,也就是說,將給定標(biāo)記名和版本號的bundle與其他擁有相同標(biāo)記名(區(qū)分大小寫)和精確版本號的bundle進(jìn)行比較。
當(dāng)安裝一個(gè)與已經(jīng)存在的bundle具有相同標(biāo)記名和版本號的bundle時(shí),必須安裝失敗。
一個(gè)bundle的標(biāo)記名是開發(fā)者給定的。
The Bundle-SymbolicName manifest header must conform to the following syntax:
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的解析不會影響到其他具有相同標(biāo)記名的非單例bundle。
• fragment-attachment - 定義了片段是如何被附加的,有以下值:
• always - 當(dāng)bundle被解析后或在解析期間,片段始終被附加著
• never - 不允許附加片段
• resolve-time - 片段只能在解析期間被附加
例如:
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是一個(gè)可選的頭,它的默認(rèn)值是0.0.0。
如果主版本號或三級版本號部分沒有被指定,它們將被設(shè)置成默認(rèn)值0. 如果版本界定給沒有指定(Alpha, Beta等),則為空字符串。
版本號是可對比的。這個(gè)比較是通過major, minor, and micro的順序比較它們的數(shù)字大小,然后使用String類的compareTo方法來比較版本界定來完成的。
一個(gè)版本和另一個(gè)版本相同意味著major, minor, micro 和 qualifier 都要相同
例如:
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-names ( ';' parameter )*
package-names ::= package-name( ';' package-name )* // See 1.3.2
這個(gè)頭允許很多包被引入。一個(gè)引入的定義是對一個(gè)bundle的一個(gè)包的描述。這個(gè)語法允許以分號隔開的多個(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表示包是可選的。
開發(fā)者可以指定專有匹配屬性:
• version - 一個(gè)選擇輸出包版本的版本范圍。語法必須遵循28頁(原規(guī)范中的28頁)中版本范圍的語法。如果這個(gè)屬性沒有被指定,默認(rèn)值為[0.0.0, ∞),就是所有版本都可以用。
• specification-version - 這個(gè)屬性是version的別名,僅僅只是為了使升級更簡單(從早期版本移植過來)。如果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)多次,或
• 多次定義對同一個(gè)包的引入
正確定義的列子:
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-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類似。僅僅只是一些指令和屬性不同
這個(gè)頭允許包被輸出。一個(gè)輸出的定義是對為一個(gè)bundle輸出一個(gè)包的描述。這個(gè)語法允許將輸出多個(gè)包的聲明定義在一個(gè)以分號分隔的子句中。對同 一個(gè)包的多個(gè)輸出定義是允許的,例如,對于不同的引入者,需要使用不同的屬性的時(shí)候。(比如2個(gè)引入者需要的是2個(gè)不同的這個(gè)bundle的版本,但是這 個(gè)bundle對這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 - 給輸出包使用的以逗號分隔的包名的列表。注意值中逗號的使用,它需要被雙引號括起來。如果一個(gè)輸出包被引入包選中,那么解析者(框架)需要確保引入包引入的是列表中與之版本號相同的包。
• mandatory - 以逗號分隔的屬性名的列表。注意值中逗號的使用,它需要被雙引號括起來。一個(gè)引入這個(gè)包的bundle必須指定mandatory屬性和一個(gè)匹配值,用于解析到輸出包。
• 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.
以下屬性是這部分規(guī)范的一部分:
• version - 以定義在page28中的語法命名的包的版本號。它定義了關(guān)聯(lián)的包的版本。默認(rèn)值0.0.0。
• specification-version - 屬性version的別名.
另外,專有匹配屬性可以被指定。框架會自動以下列屬性關(guān)聯(lián)每一個(gè)包的輸出定義(這個(gè)屬性只是出現(xiàn)在importer中,用來匹配輸出包,而不能出現(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è)自動引入定義。一個(gè)輸出了一個(gè)包的bundle并不會引入這個(gè)包,而是通過bundle classpath來獲取這個(gè)包,這樣一個(gè)輸出了的包只能被其他bundles使用,但是輸出bundle不會接受從另外一個(gè)bundle而來的這個(gè)包的 替代品。(理解為,一個(gè)bundle含有package com.foo,自己需要這個(gè)package,也輸出這個(gè)package,而一個(gè)bundle也同樣輸出這個(gè)package,第一個(gè)bundle不會使用 第二個(gè)bundle中的package,而是通過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è)包并不意味著對這個(gè)包的引入(不過在第三版中,輸出意味著引入)。這樣做的原因是使一個(gè)bundle為其他bundles提供
package,不需要考慮這個(gè)包會被解析者以其他bundle中相同的package替換。這在一個(gè)應(yīng)用程序是由一系列相互引用其實(shí)現(xiàn)包的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的內(nèi)部運(yùn)作能力是很重要的。在java,bundles的內(nèi)部操作僅僅只能當(dāng)它們?yōu)橄嗤腸lasses使用相同的
class
loader才能進(jìn)行。因此,2個(gè)bundles,輸出了相同的package,但是不能引入它,不能從它那獲取共享對象。這對像Service
Layer這樣的協(xié)作機(jī)制來說是很重要的。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應(yīng)該引入輸出的packages,允許解析者替換那些包含了接口和其他共享對象的packages。這個(gè)替換允許bundles通過service注冊和其他機(jī)制來進(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中定義的頭。框架必須將版本3中的頭映射為版本4中合適的頭:
• Import-Package –一個(gè)引入定義必須修改規(guī)范版本屬性為版本屬性。不含規(guī)范屬性的引入定義不需要做任何修改,因?yàn)榘姹?中的默認(rèn)值也是0.0.0
• Export-Package –
一個(gè)輸出定義必須修改規(guī)范版本屬性為版本屬性。輸出定義必須附加指令uses。uses指令必須包含所有為這個(gè)給定的bundle引入的和輸出的
packages。另外,如果package沒有引入定義,那么必須為它添加一個(gè)含有給定版本的引入定義。
• DynamicImport-Package – 動態(tài)引入定義沒有變化。
一個(gè)bundle的manifest包含了多個(gè)版本的混合語法是錯(cuò)誤的,并且必須是這個(gè)bundle的安裝失敗。在版本2的headers中,屬性specification-version是deprecated的,應(yīng)該使用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.
框架的包解析者必須提供一些機(jī)制來將引入匹配到輸出。以下章節(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.
這段是對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ī)制,通過它,一個(gè)引入定義可以聲明一個(gè)準(zhǔn)確的版本號或版本范圍來匹配一個(gè)輸出定義。
版本范圍將兼容性通過編碼假設(shè)出來。本規(guī)范沒有定義任何兼容性策略;這個(gè)策略留給指定版本范圍的引入者,一個(gè)版本范圍包含下列策略:
• major - 不兼容更新(理解為,如果這個(gè)值被修改,則與其他版本不兼容,例如2.0是不兼容1.9的)
• minor – 向下兼容更新 (例如 1.3是兼容1.2的)
• micro – 不影響接口的改變,例如一個(gè)BUG的修正
一個(gè)引入定義必須指定一個(gè)(引入)版本范圍,就像屬性version一樣,并且輸出者必須指定一個(gè)(輸出)版本就像它的version屬性一樣。匹配是通過28頁關(guān)于版本范圍中描述的版本范圍匹配的規(guī)則來完成的。
例如,以下引入和輸出定義可以正確解析,因?yàn)橐攵x中的版本范圍匹配輸出定義中的版本范圍:
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è)包來正確解析,但是如果這個(gè)包可用那么它可能會用到這個(gè)包。例如,logging是很重要的包,但是即使沒有它也不會妨礙這個(gè)bundle運(yùn)行。
可以通過以下方式指定可選引入:
• Dynamic Imports –頭DynamicImport-Package是指需要的時(shí)候查找一個(gè)輸出包,動態(tài)引入最典型的例子是Class的forName方法,一個(gè)bundle沒有預(yù)先知道一個(gè)可能需要被加載的類。
• Resolution Directive – 指令resolution,一個(gè)引入定義指定值optional。如果沒有給出一個(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í)候。嘗試為每一次動態(tài)引入創(chuàng)建一個(gè)連接,并嘗試加載包中的類,相反僅當(dāng)bundle被解析之后,才可能會為resolution optional包創(chuàng)建連接。
引入定義的指令resolution可以被賦值mandatory或optional。
• mandatory –表示解析包的時(shí)候包必須被連接(默認(rèn)值)。
• optional – 表示引入bundle可能被解析而不需要連接包。
下面這個(gè)例子會解析bundle A,即使bundle沒有提供匹配的版本
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)必須處理包可能不可用的情況,也就是說,當(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.
類可以依賴其他包中的類。例如,當(dāng)它們擴(kuò)展其他包中的類,或其他包中的類做為屬性存在時(shí)。因此可以說成是一個(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對每個(gè)包只有一個(gè)輸出者, Class space consistency僅僅只能被確定。例如,Http Service實(shí)現(xiàn)需要servlets繼承基類javax.servlet.http.HttpServlet,如果Http Service bundle要引入版本2.4,client bundle 要引入版本2.1,那么一定要產(chǎn)生類型轉(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è)包的輸出定義就意味著通過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í),解析者必須通過約束暗指連接這個(gè)引入到輸出者。這個(gè)輸出者可能會依次暗示附加約束,等等。因此連接一個(gè)單 一的包的引入到一個(gè)輸出者的動作能暗指很多約束。術(shù)語implied package constraints引用了一系列通過遞歸完成連接構(gòu)造而來的約束。它不會自動引入,相反,它僅僅只是約束了一個(gè)引入定義如何被解析。
例如,圖3.16,bundle A引入包p。假設(shè)這個(gè)引入定義被連接到bundle B。由于使用了uses指令(橢圓形標(biāo)記表示使用uses指令),這就暗指一個(gè)約束到包q。
然后,假設(shè)對包q的引入被連接到bundle C,那么這就暗指了一個(gè)約束到對包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ù)類空間的連貫性,框架必須確保bundle的引入不會與bundle的暗指包發(fā)生沖突。
例如,框架必須確保A.t的引入定義是連接到包D.t的。將這個(gè)引入定義連接到包F.t會破壞類空間的連貫性。
因?yàn)閎undle A能得到相同類名的對象,但是確是從bundle D和F的class loader得到的,這就潛藏著ClassCastExceptions。作為另一種方案,如果所有的bundles都連接到F.t,就不會存在這個(gè)問題了。
這個(gè)案例的另外一種情況描述于圖3.15. bundle A從B那引入類Http Service。bundle B又包含org.osgi.service.http和javax.servlet,因此bundle A約束javax.servlet連接到像連接bundle B一樣的輸出者。
做為一個(gè)不可能使用uses指令解析的例子,考慮以下可以被正確解析的設(shè)置 :
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則不行:
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,因此它由于類空間約束而不能被解析。
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è)常見的機(jī)制,允許引入者和輸出者以聲明的方式影響匹配過程。為了使一個(gè)引入定義被解析到一個(gè)輸出定義,引入定義指定的屬性的值必須匹配輸出 定義的屬性的值。默認(rèn)情況下,輸出定義包含的屬性可以不必出現(xiàn)在引入定義中。相反,輸出定義中的指令mandatory 列出的所有屬性,框架必須將其與引入定義的屬性匹配。
For example, the following statements will match.
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屬性當(dāng)引入者沒有引用的時(shí)候被忽略。默認(rèn)情況下屬性是可選的。
輸出者可以在輸出定義中通過mandatory 指令來指定強(qiáng)制屬性。這個(gè)指令包含了以逗號隔開的屬性名的列表,它們必須被引入者指定用于匹配。
例如,下面的引入定義不能匹配輸出定義,因?yàn)閟ecurity是強(qiáng)制屬性
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è)輸出者能在輸出定義中通過include和exclude指令限制一個(gè)包中的類的可見性。這兩個(gè)指令的值都是以逗號分隔的類名列表。注意值中逗號的使用,它需要被雙引號括起來。
類名必須包含他們的包名并且不以.class結(jié)尾。也就是說,com.acme.foo.Daffy是是其中一個(gè)列表中名為Daffy的對象。類名也可以包含多個(gè)通配符('*')。
include指令的默認(rèn)值是'*',對于exclude指令來說是空列表,匹配空名,因此沒有類或資源被拒絕。如果yinclude或exclude指令被指定,相應(yīng)的默認(rèn)值要被重載。
一個(gè)類僅僅只能因下列因素而可見:
• 匹配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的順序沒有特殊要求。
下面這個(gè)例子顯示了一個(gè)輸出聲明,和一個(gè)文件列表以及它們的可見性狀態(tài)。
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.
使用過濾器的時(shí)候必須注意,例如,一個(gè)具有向下兼容的新版本模塊,不應(yīng)該過濾掉那些沒有被前面的版本過濾掉的類或資源。另外,將現(xiàn)有代碼模塊化,從一個(gè)輸出包中過濾類或資源可能會打斷包的使用者。
例如,標(biāo)準(zhǔn)結(jié)構(gòu)定義的包經(jīng)常會需要一個(gè)標(biāo)準(zhǔn)包中的實(shí)現(xiàn)類,用于訪問規(guī)范類。
public class Specified {
static Specified implementation;
public void foo() {
implementation.foo();
}
}
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不可用,因?yàn)樗试Simplementation被設(shè)置。通過拒絕類Implementation,僅僅只有輸出bundle能看見它,輸出定義可以這樣:
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 arange 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)引入者與輸出者之間沒有規(guī)范約定的時(shí)候。引入者嚴(yán)密的將自己連接到指定的輸出者,特別是在測試的時(shí)候。為了放寬連接,引入者能指定一個(gè)bundle版本的范圍來匹配。
引入者能通過屬性bundle-symbolic- name和bundle-version選擇一個(gè)輸出者。框架自動為每一個(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ī)則來匹配。引入定義必須是一個(gè)版本范圍,輸出定義必須是一個(gè)版本值。
例如,下面的定義會被匹配:
Import-Package: com.acme.foo;
bundle-symbolic-name=B;
bundle-version="[1.41,2.0.0)"
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:
下面的聲明不會被匹配,因?yàn)锽沒有指定版本,而是使用默認(rèn)值0.0.0
Import-Package: com.acme.foo;
bundle-symbolic-name=B;
bundle-version="[1.41,2.0.0)"
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.
通過標(biāo)記名來選擇一個(gè)輸出者會得到一個(gè)比較模糊的結(jié)果,因?yàn)閷τ赽undle來說是硬連接。例如,如果一個(gè)輸出者最終需要被重構(gòu)成多個(gè)bundles,所有的引入者必須被修改。其他專有匹配屬性就沒有這個(gè)缺點(diǎn),因?yàn)樗鼈兡鼙华?dú)立指定到輸出bundle。
在重構(gòu)中,bundle標(biāo)記名的模糊問題,可以通過寫一個(gè)具有相同標(biāo)記名的門戶bundle作為原先的那個(gè)bundle來分成幾塊解決。
轉(zhuǎn)自:http://www.aygfsteel.com/Phrancol/articles/189711.html
posted on 2008-05-08 19:00 gembin 閱讀(1086) 評論(0) 編輯 收藏 所屬分類: OSGi