随笔 - 1  文章 - 37  trackbacks - 0
<2024年3月>
252627282912
3456789
10111213141516
17181920212223
24252627282930
31123456

留言簿(16)

随笔分类

随笔档案

文章分类

文章档案

test

搜索

  •  

最新评论

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指定了一个唯一的,非本地化的名字,这个名字应该反转于域名结构。这个头必须被指定

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的版本,默认值是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来分成几块解决。
posted on 2008-04-03 16:23 Phrancol Yang 阅读(1656) 评论(0)  编辑  收藏 所属分类: OSGI

只有注册用户登录后才能发表评论。


网站导航: