Version 1.4
3.1 Introduction
The standard Java platform provides only limited support for
packaging, deploying, and validating Java-based applications and
components. Because of this, many Java-based projects, such as JBoss
and NetBeans, have resorted to creating custom module-oriented layers
with specialized class loaders for packaging, deploying, and validating
applications and components. The OSGi Framework provides a generic and
standardized solution for Java modularization.
标准的JAVA平台对打包,部署和验证基于JAVA的应用程序和组件仅仅提供了有限的支持。所以许多基于JAVA的项目,例如JBoss和
NetBeans,都通过编写自己的类加载器生成面向模块的层来打包,部署和验证应用程序和组件。OSGi框架为java模块化提供了一个通用的标准的解
决方案。
3.2 Bundles
The Framework defines a unit of modularization, called a bundle. A
bundle is comprised of Java classes and other resources, which together
can provide functions to end users. Bundles can share Java packages
among an exporter bundle and an importer bundle in a well-defined way.
In the OSGi Service Platform, bundles are the only entities for deploying Java-based applications.
A bundle is deployed as a Java ARchive (JAR) file. JAR files are
used to store applications and their resources in a standard ZIP-based
file format. This format is defined by [27] Zip File Format.
A bundle is a JAR file that:
• Contains the resources necessary to provide some functionality.
These resources may be class files for the Java programming language,
as well as other data such as HTML files, help files, icons, and so on.
A bundle JAR file can also embed additional JAR files that are
available as resources and classes. This is however not recursive.
• Contains a manifest file describing the contents of the JAR file
and providing information about the bundle. This file uses headers to
specify information that the Framework needs to install correctly and
activate a bundle. For example, it states dependencies on other
resources, such as Java packages, that must be available to the bundle
before it can run.
• Can contain optional documentation in the OSGI-OPT directory of
the JAR file or one of its sub-directories. Any information in this
directory is optional. For example, the OSGI-OPT directory is useful to
store the source code of a bundle. Management systems may remove this
information to save storage space in the OSGi Service Platform.
Once a bundle is started, its functionality is provided and services
are exposed to other bundles installed in the OSGi Service Platform.
OSGi框架定义了模块化的单位,称为bundle。一个bundle由java类和资源组成,它们能给终端用户使用。在具备良好定义的前提下,导出bundle与引入bundle之间能共享java package。
在OSGi平台,bundle是用于部署基于java应用程序的唯一实体。
一个bundle被部署为一个JAR文件,JAR文件是一个标准的ZIP格式文件用于保存应程序和资源。
一个bundle文件:
• 包含提供某些功能所需的必要资源。这些资源可能是JAVA类文件,也可能是HTML文件,帮助文件,图标等其他文件。一个bundle jar文件中也能嵌入其他的JAR文件作为资源和类文件,当然这不能是一个循环嵌套。
•
包含一个manifest文件,用于描述JAR文件的内容和提供与bundle相关的信息。manifest文件使用头的形式来指定OSGi框架能正确安
装和激活bundle所需的信息。例如,它声明了诸如java包这样的所依赖的资源,这些java包在bundle运行之前必须对它是可用的。
• 能在OSGI-OPT目录或其子目录中包含可选文档,所有在这个目录中的信息都是可选的。例如OSGI-OPT目录可用来存放bundle的源代码。不过OSGi平台管理系统可能会删除这些信息用于保存存储空间
一个bundle一旦被启动,它将给其他已经安装在平台中的bundle提供它的功能,暴露它的services
3.2.1 Bundle Manifest Headers
A bundle can carry descriptive information about itself in the
manifest file that is contained in its JAR file under the name of
META-INF/MANIFEST.MF.
The Framework defines OSGi manifest headers such as Export-Package
and Bundle-Classpath, which bundle developers use to supply descriptive
information about a bundle. Manifest headers must strictly follow the
rules for manifest headers as defined in [28] Manifest Format.
A Framework implementation must:
• Process the main section of the manifest. Individual sections of
the manifest are only used during bundle signature verification.
• Ignore unrecognized manifest headers. The bundle developer can define additional manifest headers as needed.
• Ignore unknown attributes and directives.
All specified manifest headers are listed in the following sections. All headers are optional, unless specifically indicated.
一个bundle可以在manifest文件中携带与它自己有关的描述信息,这个文件被包含在bundle jar文件中META-INF目录中名为MANIFEST.MF。
OSGi框架定义的诸如Export-Package 和Bundle-Classpath 的manifest头是bundle开发者用来提供与bundle有关的描述信息,Manifest头必须严格按照[28]manifest Format中定义的规则。
一个实现框架必须:
• 处理manifest的主片段。manifest中的每一个片段仅仅在bundle的签名验证的过程中使用。
• 忽略为被定义的头。bundle开发者能根据需要定义额外的头。
• 忽略未知属性和标识
所有被指定的头都被列在下面的内容中。如非特殊说明,所有头都是可选的。
3.2.1.1 Bundle-ActivationPolicy: lazy
The Bundle-ActivationPolicy specifies how the framework should
activate the bundle once started. See Activation Policies on page 85.
框架启动时如何激活这个bundle
3.2.1.2 Bundle-Activator: com.acme.fw.Activator
The Bundle-Activator header specifies the name of the class used to start and stop the bundle. See Starting Bundles on page 83.
启动和停止bundle的类名
3.2.1.3 Bundle-Category: osgi, test, nursery
The Bundle-Category header holds a comma-separated list of category names.
bundle的类别
3.2.1.4 Bundle-Classpath: /jar/http.jar,.
The Bundle-Classpath header defines a comma-separated list of JAR
file path names or directories (inside the bundle) containing classes
and resources. The period ('.') specifies the root directory of the
bundle's JAR. The period is also the default. See Bundle Class Path on
page 49.
定义了以逗号分隔的jar文件路径或bundle中包含类和资源的目录的列表。点表示bundle jar的根目录,它也是默认路径。
3.2.1.5 Bundle-ContactAddress: 2400 Oswego Road, Austin, TX 74563
The Bundle-ContactAddress header provides the contact address of the vendor.
bundle提供者的联系方式
3.2.1.6 Bundle-Copyright: OSGi (c) 2002
The Bundle-Copyright header contains the copyright specification for this bundle.
bundle提供者的版权说明
3.2.1.7 Bundle-Description: Network Firewall
The Bundle-Description header defines a short description of this bundle.
bundle的描述
3.2.1.8 Bundle-DocURL: http:/www.acme.com/Firewall/doc
The Bundle-DocURL headers must contain a URL pointing to documentation about this bundle.
bundle的文档URL
3.2.1.9 Bundle-Localization: OSGI-INF/l10n/bundle
The Bundle-Localization header contains the location in the bundle
where localization files can be found. The default value is
OSGI-INF/l10n/bundle. Translations are by default therefore
OSGI-INF/l10n/bundle_de.properties, OSGI-INF/l10n/bundle_nl.properties,
etc. See Manifest Localization on page 63.
包含了一个在bundle中可以找到本地化文件的路径。默认值是OSGI-INF/l10n/bundle 。
3.2.1.10 Bundle-ManifestVersion: 2
The Bundle-ManifestVersion header defines that the bundle follows
the rules of this specification. The Bundle-ManifestVersion header
determines whether the bundle follows the rules of this specification.
It is 1 (the default) for Release 3 Bundles, 2 for Release 4 and later.
Future version of the OSGi Service Platform can define higher numbers
for this header.
定义了bundle所遵循的规范的版本号,这个头决定了bundle是否遵循这个规范的规则。
3.2.1.11 Bundle-Name: Firewall
The Bundle-Name header defines a readable name for this bundle. This
should be a short, human-readable name that can contain spaces.
为bundle 定义了一个可读取得名字,它应该是个较短的,易识别的名字,可以包含空格。
3.2.1.12 Bundle NativeCode: /lib/http.DLL; osname = QNX; osversion = 3.1
The Bundle-NativeCode header contains a specification of native code
libraries contained in this bundle. See Loading Native Code Libraries
on page 57.
3.2.1.13 Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0
The Bundle-RequiredExecutionEnvironment contains a comma-separated
list of execution environments that must be present on the Service
Platform. See Execution Environment on page 31.
bundle的可被执行环境
3.2.1.14 Bundle-SymbolicName: com.acme.daffy
The Bundle-SymbolicName header specifies a unique, non-localizable
name for this bundle. This name should be based on the reverse domain
name convention, see Bundle-SymbolicName on page 35. This header must
be set.
为bundle指定了一个唯一的,非本地化的名字,这个名字应该反转于域名结构。这个头必须被指定
The Bundle-UpdateLocation header specifies a URL where an update for
this bundle should come from. If the bundle is updated, this location
should be used, if present, to retrieve the updated JAR file.
指定了该bundle更新的URL。
3.2.1.16 Bundle-Vendor: OSGi Alliance
The Bundle-Vendor header contains a human-readable description of the bundle vendor.
bundle提供者的描述
3.2.1.17 Bundle-Version: 1.1
The Bundle-Version header specifies the version of this bundle. See Version on page 28. The default value is 0.0.0
bundle的版本,默认值是0.0.0
3.2.1.18 DynamicImport-Package: com.acme.plugin.*
The DynamicImport-Package header contains a comma-separated list of
package names that should be dynamically imported when needed. See
Dynamic Import Package on page 51.
包含了一个以逗号分隔的包名的列表,列表中的包应该在需要的时候被动态引入
3.2.1.19 Export-Package: org.osgi.util.tracker;version=1.3
The Export-Package header contains a declaration of exported packages. See Export-Package on page 37.
声明被输出的包
3.2.1.20 Export-Service: org.osgi.service.log.LogService
Deprecated.
3.2.1.21 Fragment-Host: org.eclipse.swt; bundle-version="[3.0.0,4.0.0)"
The Fragment-Host header defines the host bundle for this fragment. See Fragment-Host on page 69
为这个片段定义一个主机bundle
3.2.1.22 Import-Package: org.osgi.util.tracker,org.osgi.service.io;version=1.4
The Import-Package header declares the imported packages for this bundle. See Import-Package Header on page 36.
为这个bundle声明引入的包
3.2.1.23 Import-Service: org.osgi.service.log.LogService
Deprecated
3.2.1.24 Require-Bundle: com.acme.chess
The Require-Bundle header specifies the required exports from another bundle. Require-Bundle on page 65
指定所依赖bundle
3.4 Class Loading Architecture
Many bundles can share a single virtual machine (VM). Within this
VM, bundles can hide packages and classes from other bundles, as well
as share packages with other bundles.
The key mechanism to hide and share packages is the Java class
loader that loads classes from a sub-set of the bundle-space using
well-defined rules. Each bundle has a single class loader. That class
loader forms a class loading delegation network with other bundles as
shown in Figure 3.8.
bundles能在同一个虚拟机中,在这个虚拟机中,bundles能对其他bundles隐藏包和类,也能对其他bundles共享包和类。
隐藏和共享包的关键是java class loader通过良好定义规则从bundle空间的子集(子class
loader)中加载类。每一个bundle都有一个class loader,这个class loader与其他bundles的class
loader形成了一个类加载委派网络,如图
The class loader can load classes and resources from:
• Boot class path - The boot class path contains the java.* packages and its implementation packages.
• Framework class path - The Framework usually has a separate class
loader for the Framework implementation classes as well as key service
interface classes.
• Bundle Space - The bundle space consists of the JAR file that is
associated with the bundle, plus any additional JAR that are closely
tied to the bundle, like fragments, see Fragment Bundles on page 68.
A class space is then all classes reachable from a given bundle's
class loader. Thus, a class space for a given bundle can contain
classes from:
• The parent class loader (normally java.* packages from the boot class path)
• Imported packages
• Required bundles
• The bundle's class path (private packages)
• Attached fragments
A class space must be consistent, such that it never contains two
classes with the same fully qualified name (to prevent Class Cast
Exceptions). However, separate class spaces in an OSGi Platform may
contain classes with the same fully qualified name. The modularization
layer supports a model where multiple versions of the same class are
loaded in the same VM.
class loader能够从以下位置加载类和资源:
• boot类路径 - boot类路径包含了java.*的包和它们的实现包(可以理解为应用服务器的类路径)
• 框架类路径 - 通常框架会有不同的class loader 去加载框架的实现类,和主服务接口类。
• bundle空间 - bundle空间由与bundle相关联的jar文件组成,加上其他包含在bundle中的jar文件
那么一个类空间则可以从一个给定的bundle的class loader中获取。因此,一个给定的bundle的类空间包含的类可以来自以下方面:
• 父class loader(通常是boot类路径中的java.*包)
• 引入的包
• 所依赖的包
• bundle的类路径(私有包)
• 附加的片段(例如附加的jar包)
一个类空间必须是consistent(用哪个词来形容不可包含相同名字的两个元素?),这样它不能包含2个具有相同名字的类。不过,相同OSGi平台中不同的类空间可以包含两个名字相同的类。模块化层支持一个类的多个版本被加载在同一个虚拟机中。
The Framework therefore has a number of responsibilities related to
class loading. Before a bundle is used, it must resolve the constraints
that a set of bundles place on the sharing of packages. Then select the
best possibilities to create a wiring. See Resolving Process on page 48
for further information. The runtime aspects are described in Runtime
Class Loading on page 49.
因此对于类加载,框架有很多工作要做。在bundle被使用之前,它必须解析一系列bundles上的共享包的约束,然后选择最佳方式去搭配它们
3.4.1 Resolving
The Framework must resolve bundles. Resolving is the process where
importers are wired to exporters. Resolving is a process of satisfying
constraints. This process must take place before any code from a bundle
can be loaded or executed.
A wire is an actual connection between an exporter and an importer,
which are both bundles. A wire is associated with a number of
constraints that are defined by its importer's and exporter's manifest
headers. A valid wire is a wire that has satisfied all its constraints.
Figure 3.10 depicts the class structure of the wiring model.
框架必须解析bundle。解析是将引入者搭配到输出者的过程,也是满足约束的过程。这个过程必须在bundle中的代码被加载或执行之前进行。
搭配,是输出者与引入者之间的真实连接,一个有效的搭配是满足了所有约束的链接。
3.5 Resolving Metadata
The following sections define the manifest headers that provide the metadata for the resolver.
以下章节定义了为解析者提供元数据的manifest头
3.5.1 Bundle-ManifestVersion
A bundle manifest must express the version of the OSGi manifest
header syntax in the Bundle-ManifestVersion header. Bundles exploiting
this version of the Framework specification (or later) must specify
this header. The syntax of this header is as follows:
一个bundle的manifest必须在头Bundle-ManifestVersion中明确表示这个OSGi manifest头语法的版本号。bundle必须使用这个头。
Bundle-ManifestVersion ::= number // See 1.3.2
The Framework version 1.3 (or later) bundle manifest version must be’2’.
Bundle manifests written to previous specifications’ manifest syntax are
taken to have a bundle manifest version of '1', although there is no way to
express this in such manifests. Therefore, any other value than ’2’ for this
header is invalid unless the Framework explicitly supports such a later version.
OSGi Framework implementations should support bundle manifests without
a Bundle-ManifestVersion header and assume Framework 1.2 compatibility
at the appropriate places.
Version 2 bundle manifests must specify the bundle symbolic name. They
need not specify the bundle version since this version header has a default
value.
1.3或以后版本的框架中的bundle manifest版本必须是2,以前的版本则为1,因此所有值不是2的头均为不可用的头,除非框架明确支持。
OSGi实现框架应该支持不含Bundle-ManifestVersion头的bundle manifest,并且兼容1.2。
版本2的bundle manifest必须指定bundle标记名,可以不用指定bundle版本,因为版本头有默认值(0.0.0)
3.5.2 Bundle-SymbolicName
The Bundle-SymbolicName manifest header is a mandatory header. The
bundle symbolic name and bundle version allow a bundle to be uniquely
identified in the Framework. That is, a bundle with a given symbolic
name and version is treated as equal to another bundle with the same
(case sensitive) symbolic name and exact version.
The installation of a bundle with a Bundle-SymbolicName and Bundle-Version identical to an existing bundle must fail.
A bundle gets its unique Bundle-SymbolicName from the developer (The
Bundle-Name manifest header provides a human-readable name for a bundle
and is therefore not replaced by this header).
Bundle-SymbolicName 是一个必须的头,框架可以使用bundle标记名和版本号来识别bundle的唯一性,也就是说,将给定标记名和版本号的bundle与其他拥有相同标记名(区分大小写)和精确版本号的bundle进行比较。
当安装一个与已经存在的bundle具有相同标记名和版本号的bundle时,必须安装失败。
一个bundle的标记名是开发者给定的。
The Bundle-SymbolicName manifest header must conform to the following syntax:
Bundle-SymbolicName ::= symbolic-name ( ';' parameter ) * // See 1.3.2
The framework must recognize the following directives for the Bundle-SymbolicName header:
• singleton - Indicates that the bundle can only have a single
version resolved. A value of true indicates that the bundle is a
singleton bundle. The default value is false. The Framework must
resolve at most one bundle when multiple versions of a singleton bundle
with the same symbolic name are installed. Singleton bundles do not
affect the resolution of non-singleton bundles with the same symbolic
name.
• fragment-attachment - Defines how fragments are allowed to be
attached, see the fragments in Fragment Bundles on page 68. The
following values are valid for this directive:
• always - Fragments can attach at any time while the host is resolved or during the process of resolving.
• never - No fragments are allowed.
• resolve-time - Fragments must only be attached during resolving.
For example:
Bundle-SymbolicName: com.acme.foo;singleton:=true
框架必须为头Bundle-SymbolicName提供以下属性的支持:
• singleton -
表示该bundle仅仅只能有一个版本被解析。值为true表示一个单例bundle,否则为多例。当具有相同标记名的多个版本的单例bundle被安装
的时候,框架必须最多只能解析一个bundle。单例bundle的解析不会影响到其他具有相同标记名的非单例bundle。
• fragment-attachment - 定义了片段是如何被附加的,有以下值:
• always - 当bundle被解析后或在解析期间,片段始终被附加着
• never - 不允许附加片段
• resolve-time - 片段只能在解析期间被附加
例如:
Bundle-SymbolicName: com.acme.foo;singleton:=true
3.5.3 Bundle-Version
Bundle-Version is an optional header; the default value is 0.0.0.
Bundle-Version ::= version // See 3.2.4
If the minor or micro version components are not specified, they
have a default value of 0. If the qualifier component is not specified,
it has a default value of the empty string ("").
Versions are comparable. Their comparison is done numerically and
sequentially on the major, minor, and micro components and lastly using
the String class compareTo method for the qualifier.
A version is considered equal to another version if the major,
minor, micro, and the qualifier components are equal (using String
method compareTo).
Example:
Bundle-Version: 22.3.58.build-345678
Bundle-Version是一个可选的头,它的默认值是0.0.0。
如果主版本号或三级版本号部分没有被指定,它们将被设置成默认值0. 如果版本界定给没有指定(Alpha, Beta等),则为空字符串。
版本号是可对比的。这个比较是通过major, minor, and micro的顺序比较它们的数字大小,然后使用String类的compareTo方法来比较版本界定来完成的。
一个版本和另一个版本相同意味着major, minor, micro 和 qualifier 都要相同
例如:
Bundle-Version: 22.3.58.build-345678
3.5.4 Import-Package Header
The Import-Package header defines the constraints on the imports of shared packages. The syntax of the Import-Package header is:
Import-Package ::= import ( ',' import )*
import ::= package-names ( ';' parameter )*
package-names ::= package-name( ';' package-name )* // See 1.3.2
The header allows many packages to be imported. An import definition
is the description of a single package for a bundle. The syntax permits
multiple package names, separated by semi-colons, to be described in a
short form.
头Import-Package定义了对共享包的引入的约束。语法如下
Import-Package ::= import ( ',' import )*
import ::= package-names ( ';' parameter )*
package-names ::= package-name( ';' package-name )* // See 1.3.2
这个头允许很多包被引入。一个引入的定义是对一个bundle的一个包的描述。这个语法允许以分号隔开的多个包名被描述在这个结构中。
Import package directives are:
• resolution - Indicates that the packages must be resolved if the
value is mandatory, which is the default. If mandatory packages cannot
be resolved, then the bundle must fail to resolve. A value of optional
indicates that the packages are optional. See Optional Packages on page
42.
The developer can specify arbitrary matching attributes. See
Attribute Matching on page 45. The following arbitrary matching
attributes are predefined:
• version - A version-range to select the exporter's package
version. The syntax must follow Version Ranges on page 28. For more
information on version selection, see Version Matching on page 41. If
this attribute is not specified, it is assumed to be [0.0.0, ∞).
• specification-version - This attribute is an alias of the version
attribute only to ease migration from earlier versions. If the version
attribute is present, the values must be equal.
• bundle-symbolic-name - The bundle symbolic name of the exporting
bundle. In the case of a Fragment bundle, this will be the host
bundle's symbolic name.
• bundle-version - A version-range to select the bundle version of the
exporting bundle. The default value is [0.0.0, ∞). See Version Matching
on page 41. In the case of a Fragment bundle, the version is from the
host bundle.
引入包有以下指令:
• resolution - 如果值为mandatory,表示这个包必须被解析,这是默认值。如果一个mandatory包不能被解析,那么这个bundle将解析失败。值optional表示包是可选的。
开发者可以指定专有匹配属性:
• version - 一个选择输出包版本的版本范围。语法必须遵循28页(原规范中的28页)中版本范围的语法。如果这个属性没有被指定,默认值为[0.0.0, ∞),就是所有版本都可以用。
• specification-version - 这个属性是version的别名,仅仅只是为了使升级更简单(从早期版本移植过来)。如果version被指定,这两个属性的值必须相等。
• bundle-symbolic-name - 输出bundle的标记名。在具有片段bundle的例子中,这个值是宿主bundle的标记名。
• bundle-version - 输出bundle的版本范围。在具有片段bundle的例子中,这个值是宿主bundle的版本范围。
In order to be allowed to import a package (except for packages
starting with java.), a bundle must have
PackagePermission[<package-name>, IMPORT]. See PackagePermission
for more information. An error aborts an installation or update when:
• A directive or attribute appears multiple times, or
• There are multiple import definitions for the same package.
Example of a correct definition:
Import-Package: com.acme.foo;com.acme.bar;
version="[1.23,1.24]";
resolution:=mandatory
为了允许引入一个包,一个bundle必须有PackagePermission[<package-name>, IMPORT]. 当下列情况发生时必须终止安装或更新bundle:
• 一个指令或属性出现多次,或
• 多次定义对同一个包的引入
正确定义的列子:
Import-Package: com.acme.foo;com.acme.bar;
version="[1.23,1.24]";
resolution:=mandatory
3.5.5 Export-Package
The syntax of the Export-Package header is similar to the
Import-Package header; only the directives and attributes are different.
Export-Package ::= export ( ',' export )*
export ::= package-names ( ';' parameter )*
package-names ::= package-name ( ';' package-name )*// See 1.3.2
The header allows many packages to be exported. An export definition
is the description of a single package export for a bundle. The syntax
permits the declaration of multiple packages in one clause by
separating the package names with a semi-colon. Multiple export
definitions for the same package are allowed for example, when
different attributes are needed for different importers.
头Export-Package的语法与Import-Package类似。仅仅只是一些指令和属性不同
这个头允许包被输出。一个输出的定义是对为一个bundle输出一个包的描述。这个语法允许将输出多个包的声明定义在一个以分号分隔的子句中。对同
一个包的多个输出定义是允许的,例如,对于不同的引入者,需要使用不同的属性的时候。(比如2个引入者需要的是2个不同的这个bundle的版本,但是这
个bundle对这2个引入这都可用,那么就以2个版本的形式输出)
Export directives are:
• uses - A comma-separated list of package names that are used by
the exported package. Note that the use of a comma in the value
requires it to be enclosed in double quotes. If this exported package
is chosen as an export, then the resolver must ensure that importers of
this package wire to the same versions of the package in this list. See
Package Constraints on page 43.
• mandatory - A comma-separated list of attribute names. Note that the
use of a comma in the value requires it to be enclosed in double
quotes. A bundle importing the package must specify the mandatory
attributes, with a value that matches, to resolve to the exported
package. See Mandatory Attributes on page 45.
• include - A comma-separated list of class names that must be visible
to an importer. Note that the use of a comma in the value requires it
to be enclosed in double quotes. For class filtering, see Class
Filtering on page 46.
• exclude -A comma-separated list of class names that must be invisible
to an importer. Note that the use of a comma in the value requires it
to be enclosed in double quotes. For class filtering, see Class
Filtering on page 46.
输出指令有:
• uses - 给输出包使用的以逗号分隔的包名的列表。注意值中逗号的使用,它需要被双引号括起来。如果一个输出包被引入包选中,那么解析者(框架)需要确保引入包引入的是列表中与之版本号相同的包。
• mandatory - 以逗号分隔的属性名的列表。注意值中逗号的使用,它需要被双引号括起来。一个引入这个包的bundle必须指定mandatory属性和一个匹配值,用于解析到输出包。
• include - 以逗号分隔的必须对引入者可见的类名的列表。
• exclude -以逗号分隔的必须对引入者不可见的类名的列表
The following attribute is part of this specification:
• version - The version of the named packages with syntax as defined
in Version on page 28. It defines the version of the associated
packages. The default value is 0.0.0.
• specification-version - An alias for the version attribute only to
ease migration from earlier versions. If the version attribute is
present, the values must be equal.
Additionally, arbitrary matching attributes may be specified. See
Attribute Matching on page 45. The Framework will automatically
associate each package export definition with the following attributes:
• bundle-symbolic-name - The bundle symbolic name of the exporting
bundle. In the case of a Fragment bundle, this is the host bundle's
symbolic name.
• bundle-version - The bundle version of the exporting bundle. In the
case of a Fragment bundle, this is the host bundle's version.
以下属性是这部分规范的一部分:
• version - 以定义在page28中的语法命名的包的版本号。它定义了关联的包的版本。默认值0.0.0。
• specification-version - 属性version的别名.
另外,专有匹配属性可以被指定。框架会自动以下列属性关联每一个包的输出定义(这个属性只是出现在importer中,用来匹配输出包,而不能出现在输出包中):
• bundle-symbolic-name - 输出bundle的标记名。在含有片段的例子中,是宿主bundle的标记名。
• bundle-version - 输出bundle的版本。在含有片段的例子中,是宿主bundle的版本。
An installation or update must be aborted when any of the following conditions is true:
• a directive or attribute appears multiple times
• the bundle-symbolic-name or bundle-version attribute is specified in the Export-Package header.
An export definition does not imply an automatic import definition.
A bundle that exports a package and does not import that package will
get that package via its bundle class path. Such an exported only
package can be used by other bundles, but the exporting bundle does not
accept a substitution for this package from another bundle.
In order to export a package, a bundle must have PackagePermission[<package>, EXPORT].
Example:
Export-Package: com.acme.foo;com.acme.bar;version=1.23
当出现以下条件时,安装或更新必须被终止:
• 一个指令或属性出现多次
• bundle-symbolic-name 或 bundle-version 属性被指定在 Export-Package 中.
一个输出定义并非一个自动引入定义。一个输出了一个包的bundle并不会引入这个包,而是通过bundle
classpath来获取这个包,这样一个输出了的包只能被其他bundles使用,但是输出bundle不会接受从另外一个bundle而来的这个包的
替代品。(理解为,一个bundle含有package
com.foo,自己需要这个package,也输出这个package,而一个bundle也同样输出这个package,第一个bundle不会使用
第二个bundle中的package,而是通过classpath使用自己的那个package)
3.5.6 Exporting and Importing a Package
Exporting a package does not imply the import of that same package
(in Release 3, an export did imply an import). The reason for this
separation is that it enables a bundle to provide a package to other
bundles without having to take into account that the exported package
could be substituted by the resolver with the same package from another
bundle. This is a common case when an application consists of a set of
closely intertwined bundles where implementation packages are provided
to other bundles.
输出一个包并不意味着对这个包的引入(不过在第三版中,输出意味着引入)。这样做的原因是使一个bundle为其他bundles提供
package,不需要考虑这个包会被解析者以其他bundle中相同的package替换。这在一个应用程序是由一系列相互引用其实现包的bundle
的例子中是很常见的。
The substitution of packages is crucial for the inter-operability of
bundles. In Java, bundles can only inter-operate when they use the same
class loaders for the same classes. Therefore, two bundles that both
export the same package, but do not import it, cannot share objects
from that package. This is very important for a collaboration mechanism
like the Service Layer. Bundles can only use the same service objects
if their classes and interfaces come from the same class loaders.
包的替换对于bundles的内部运作能力是很重要的。在java,bundles的内部操作仅仅只能当它们为相同的classes使用相同的
class
loader才能进行。因此,2个bundles,输出了相同的package,但是不能引入它,不能从它那获取共享对象。这对像Service
Layer这样的协作机制来说是很重要的。Bundles仅仅只能使用相同的service对象,如果他们的类和接口来自相同的class
loaders。
Bundles should import exported packages, allowing the resolver to
substitute packages that contain interfaces and other shared types.
This substitution allows bundles to inter-operate through the service
registry and other mechanisms. Additionally, the import should be as
unconstrained as possible to allow the resolver maximum flexibility.
bundles应该引入输出的packages,允许解析者替换那些包含了接口和其他共享对象的packages。这个替换允许bundles通过service注册和其他机制来进行内部操作。另外,这个引入应该被尽可能不受限制而是解析者获得最大的灵活性。
3.5.7 Interpretation of Legacy Bundles 遗留bundle
Bundles that are not marked with a Bundle-ManifestVersion that
equals 2 or more must treat the headers according the definitions in
the Release 3. More specifically, the Framework must map the Release 3
headers to the appropriate Release 4 headers:
• Import-Package – An import definition must change the
specification version attribute to the version attribute. An import
definition without a specification version needs no replacement since
the default version value of 0.0.0 gives the same semantics as Release
3.
• Export-Package – An export definition must change the specification
version attribute to the version attribute. The export definition must
be appended with the uses directive. The uses directive must contain
all imported and exported packages for the given bundle. Additionally,
if there is no import definition for this package, then an import
definition for this package with the given version must be added.
• DynamicImport-Package – A dynamic import definition is unmodified.
A bundle manifest which mixes legacy syntax with bundle manifest
version 2 syntax is in error and must cause the containing bundle to
fail to install. The specification-version attribute is a deprecated
synonym for the version attribute in bundle manifest version 2 headers.
如果bundles的头Bundle-ManifestVersion的值不是2或比2大,它必须按照版本3中定义的头。框架必须将版本3中的头映射为版本4中合适的头:
• Import-Package –一个引入定义必须修改规范版本属性为版本属性。不含规范属性的引入定义不需要做任何修改,因为版本3中的默认值也是0.0.0
• Export-Package –
一个输出定义必须修改规范版本属性为版本属性。输出定义必须附加指令uses。uses指令必须包含所有为这个给定的bundle引入的和输出的
packages。另外,如果package没有引入定义,那么必须为它添加一个含有给定版本的引入定义。
• DynamicImport-Package – 动态引入定义没有变化。
一个bundle的manifest包含了多个版本的混合语法是错误的,并且必须是这个bundle的安装失败。在版本2的headers中,属性specification-version是deprecated的,应该使用version来代替它。
3.6 Constraint Solving
The OSGi Framework package resolver provides a number of mechanisms
to match imports to exports. The following sections describe these
mechanisms in detail.
框架的包解析者必须提供一些机制来将引入匹配到输出。以下章节描述了这些机制的细节。
3.6.1 Diagrams and Syntax
Wires create a graph of nodes. Both the wires as well as nodes
(bundles) carry a significant amount of information. In the next
sections, the following conventions are used to explain the many
details.
Bundles are named A, B, C,... That is, uppercase characters starting
from the character A. Packages are named p, q, r, s, t,... In other
words, lower case characters starting from p. If a version is
important, it is indicated with a dash followed by the version: q-1.0.
The syntax A.p means the package definition (either import or export)
of package p by bundle A.
Import definitions are graphically shown by a white box. Export
definitions are displayed with a black box. Packages that are not
exported or imported are called private packages. They are indicated
with diagonal lines.
Bundles are a set of connected boxes. Constraints are written on the wires,
which are represented by lines.
这段是对Figure 3.11中的定义进行描述。
For example:
A: Import-Package: p; version="[1,2)"
Export-Package: q; version=2.2.2; uses:=p
Require-Bundle: C
B: Export-Package: p; version=1.5.1
C: Export-Package: r
Figure 3.12 shows the same setup graphically.
3.6.2 Version Matching
Version constraints are a mechanism whereby an import definition can
declare a precise version or a version range for matching an export
definition.
Version ranges encode the assumptions about compatibility. This
specification does not define any compatibility policy; the policy
decision is left to the importer that specifies a version range. A
version range embeds such a policy.
However, the most common version compatibility policies are:
• major – An incompatible update
• minor – A backward compatible update
• micro – A change that does not affect the interface: for example, a bug fix
An import definition must specify a version range as the value for
its version attribute, and the exporter must specify a version as the
value for its version attribute. Matching is done with the rules for
version range matches as described in Version Ranges on page 28.
For example, the following import and export definition resolve
correctly because the version range in the import definition matches
the version in the export definition:
A: Import-Package: p; version="[1,2)"
B: Export-Package: p; version=1.5.1
Figure 3.13 graphically shows how a constraint can exclude an exporter.
版本约束是一个机制,通过它,一个引入定义可以声明一个准确的版本号或版本范围来匹配一个输出定义。
版本范围将兼容性通过编码假设出来。本规范没有定义任何兼容性策略;这个策略留给指定版本范围的引入者,一个版本范围包含下列策略:
• major - 不兼容更新(理解为,如果这个值被修改,则与其他版本不兼容,例如2.0是不兼容1.9的)
• minor – 向下兼容更新 (例如 1.3是兼容1.2的)
• micro – 不影响接口的改变,例如一个BUG的修正
一个引入定义必须指定一个(引入)版本范围,就像属性version一样,并且输出者必须指定一个(输出)版本就像它的version属性一样。匹配是通过28页关于版本范围中描述的版本范围匹配的规则来完成的。
例如,以下引入和输出定义可以正确解析,因为引入定义中的版本范围匹配输出定义中的版本范围:
A: Import-Package: p; version="[1,2)"
B: Export-Package: p; version=1.5.1
3.6.3 Optional Packages
A bundle can indicate that it does not require a package to resolve
correctly, but it may use the package if it is available. For example,
logging is important, but the absence of a log service should not
prevent a bundle from running.
Optional imports can be specified in the following ways:
• Dynamic Imports – The DynamicImport-Package header is intended to
look for an exported package when that package is needed. The key use
case for dynamic import is the Class forName method when a bundle does
not know in advance the class name it may be requested to load.
• Resolution Directive – The resolution directive on an import
definition specifying the value optional. A bundle may successfully
resolve if a suitable optional package is not present.
一个bundle能指明他不需要一个包来正确解析,但是如果这个包可用那么它可能会用到这个包。例如,logging是很重要的包,但是即使没有它也不会妨碍这个bundle运行。
可以通过以下方式指定可选引入:
• Dynamic Imports –头DynamicImport-Package是指需要的时候查找一个输出包,动态引入最典型的例子是Class的forName方法,一个bundle没有预先知道一个可能需要被加载的类。
• Resolution Directive – 指令resolution,一个引入定义指定值optional。如果没有给出一个合适的可选包那么一个bundle可能解析成功。
The key difference between these two mechanisms is when the wires
are made. An attempt is made to establish a wire for a dynamic import
every time there is an attempt to load a class in that package, whereas
the wire for a resolution optional package may only be established when
the bundle is resolved.
The resolution directive of the import definition can take the value mandatory or optional.
• mandatory – (Default) Indicates that the package must be wired for the bundle to resolve.
• optional – Indicates that the importing bundle may resolve without the package being wired.
The following example will resolve even though bundle B does not
provide the correct version (the package will not be available to the
code when bundle A is resolved).
A: Import-Package: p; resolution:=optional; version=1.6
B: Export-Package: p; q; version=1.5.0
这两个机制的关键区别是当连接生成的时候。尝试为每一次动态引入创建一个连接,并尝试加载包中的类,相反仅当bundle被解析之后,才可能会为resolution optional包创建连接。
引入定义的指令resolution可以被赋值mandatory或optional。
• mandatory –表示解析包的时候包必须被连接(默认值)。
• optional – 表示引入bundle可能被解析而不需要连接包。
下面这个例子会解析bundle A,即使bundle没有提供匹配的版本
A: Import-Package: p; resolution:=optional; version=1.6
B: Export-Package: p; q; version=1.5.0
The implementation of a bundle that uses optional packages must be prepared
to handle the fact that the packages may not be available: that is, an
exception can be thrown when there is a reference to a class from a missing
package.
使用可选包的bundle的实现必须处理包可能不可用的情况,也就是说,当引用一个不存在包的时候能抛出一个exception。
3.6.4 Package Constraints
Classes can depend on classes in other packages. For example, when they
extend classes from another package, or these other classes appear in
method signatures. It can therefore be said that a package uses other
packages.
These inter-package dependencies are modeled with the uses directive on the Export-Package header.
For example, org.osgi.service.http depends on the package javax.servlet
because it is used in the API. The export definition of the
org.osgi.service.http must therefore contain the uses directive with
the javax.servlet package as its value.
Class space consistency can only be ensured if a bundle has only one exporter for each package.
For example, the Http Service implementation requires servlets to
extend the javax.servlet.http.HttpServlet base class. If the Http
Service bundle would import version 2.4 and the client bundle would
import version 2.1 then a class cast is bound to happen. This is
depicted in Figure 3.15.
类可以依赖其他包中的类。例如,当它们扩展其他包中的类,或其他包中的类做为属性存在时。因此可以说成是一个包引用其他包。
内部包的依赖关系模拟在头Export-Package中使用指令uses。
例如,org.osgi.service.http依赖包javax.servlet,因为要使用它的API,所以org.osgi.service.http的输出定义必须包含值为javax.servlet的uses指令。
如果一个bundle对每个包只有一个输出者,
Class space consistency仅仅只能被确定。例如,Http
Service实现需要servlets继承基类javax.servlet.http.HttpServlet,如果Http Service
bundle要引入版本2.4,client bundle 要引入版本2.1,那么一定要产生类型转换。
If a bundle imports a package from an exporter then the export
definition of that package can imply constraints on a number of other
packages through the uses directive. The uses directive lists the
packages that the exporter depends upon and therefore constrains the
resolver for imports. These constraints ensure that a set of bundles
share the same class loader for the same package.
如果一个bundle从一个输出者那引入一个包,那么那个包的输出定义就意味着通过uses指令在其他包上加上了约束。uses指令列出了输出者依赖的包,因此约束了解析者的引入。这些约束确保了一系列的bundle为同一个包共享同一个classloader。
When an importer imports a package with implied constraints, the
resolver must wire the import to the exporter implied by the
constraint. This exporter may in turn imply additional constraints, and
so on. The act of wiring a single import of a package to an exporter
can therefore imply a large set of constraints. The term implied
package constraints refers to the complete set of constraints
constructed from recursively traversing the wires. Implied package
constraints are not automatic imports; rather, implied package
constraints only constrain how an import definition must be resolved.
For example, in Figure 3.16, bundle A imports package p. Assume this
import definition is wired to bundle B. Due to the uses directive (the
ellipse symbols indicates the uses directive) this implies a constraint
on package q.
Further, assuming that the import for package q is wired to bundle C,
then this implies a constraint on the import of package r and s.
Continuing, assuming C.s and C.r are wired to bundle D and E
respectively. These bundles both add package t to the set of implied
packages for bundle A.
当一个引入者以implied约束引入一个包时,解析者必须通过约束暗指连接这个引入到输出者。这个输出者可能会依次暗示附加约束,等等。因此连接一个单
一的包的引入到一个输出者的动作能暗指很多约束。术语implied package
constraints引用了一系列通过递归完成连接构造而来的约束。它不会自动引入,相反,它仅仅只是约束了一个引入定义如何被解析。
例如,图3.16,bundle A引入包p。假设这个引入定义被连接到bundle B。由于使用了uses指令(椭圆形标记表示使用uses指令),这就暗指一个约束到包q。
然后,假设对包q的引入被连接到bundle C,那么这就暗指了一个约束到对包r和s的引入。接着,假如bundle C的包s和r分别被连接到bundle D和E。这些bundle都将包t加入用于bundle A的暗指包中
To maintain class space consistency, the Framework must ensure that
none of its bundle imports conflicts with any of that bundle’s implied
packages.
For the example, this means that the Framework must ensure that the
import definition of A.t is wired to package D.t. Wiring this import
definition to package F.t violates the class space consistency. This
violation occurs because bundle A could be confronted with objects with
the same class name but from the class loaders of bundle D and F. This
would potentially create ClassCastExceptions. Alternatively, if all
bundles are wired to F.t, then the problem also goes away.
Another scenario with this case is depicted in Figure 3.15. Bundle A
imports the Http Service classes from bundle B. Bundle B has grouped
the org.osgi.service.http and the javax.servlet and bundle A is
therefore constrained to wire javax.servlet to the same exporter as
bundle B.
As an example of a situation where the uses directive makes resolving
impossible consider the following setup that is correctly resolved:
为了维护类空间的连贯性,框架必须确保bundle的引入不会与bundle的暗指包发生冲突。
例如,框架必须确保A.t的引入定义是连接到包D.t的。将这个引入定义连接到包F.t会破坏类空间的连贯性。
因为bundle A能得到相同类名的对象,但是确是从bundle D和F的class loader得到的,这就潜藏着ClassCastExceptions。作为另一种方案,如果所有的bundles都连接到F.t,就不会存在这个问题了。
这个案例的另外一种情况描述于图3.15. bundle A从B那引入类Http Service。bundle
B又包含org.osgi.service.http和javax.servlet,因此bundle
A约束javax.servlet连接到像连接bundle B一样的输出者。
做为一个不可能使用uses指令解析的例子,考虑以下可以被正确解析的设置 :
A: Import-Package: q; version="[1.0,1.0]"
Export-Package: p; uses:="q,r"
B: Export-Package: q; version=1.0
C: Export-Package: q; version=2.0
These specific constraints can be resolved because the import A.q can
be wired to the export B.q but not C.q due to the version constraint.
Adding a bundle D will now not be possible:
这个特殊的约束可以被解析,因为版本约束使A.q的引入能被连接到B.q的输出,而不是C.q。
如果再增加一个bundle D则不行:
D: Import-Package: p, q; version=2.0
Package D.p must be wired to package A.p because bundle A is the only
exporter. However, this implies the use of package q due the uses
directive in the package A.q import. Package A.q is wired to B.q-1.0.
However, import package D.q requires version 2.0 and can therefore not
be resolved without violating the class space constraint.
包D.p必须被连接到包A.p,因为bundle A是唯一一个输出者,可是,这就意味着在包A.q的引入中,包q的使用是由于uses指令。包A.q被连接到B.q-1.0.然而包D.q需要版本2.0,因此它由于类空间约束而不能被解析。
This scenario is depicted in Figure 3.17.
3.6.5 Attribute Matching
Attribute matching is a generic mechanism to allow the importer and
exporter to influence the matching process in a declarative way. In
order for an import definition to be resolved to an export definition,
the values of the attributes specified by the import definition must
match the values of the attributes of the export definition. By
default, a match is not prevented if the export definition contains
attributes that do not occur in the import definition.
The mandatory directive in the export definition can reverse this by
listing all attributes that the Framework must match in the import
definition.
Any information specified in the DynamicImport-Package is ignored during the resolve phase.
属性匹配是一个常见的机制,允许引入者和输出者以声明的方式影响匹配过程。为了使一个引入定义被解析到一个输出定义,引入定义指定的属性的值必须匹配输出
定义的属性的值。默认情况下,输出定义包含的属性可以不必出现在引入定义中。相反,输出定义中的指令mandatory
列出的所有属性,框架必须将其与引入定义的属性匹配。
For example, the following statements will match.
A: Import-Package: com.acme.foo;company=ACME
B: Export-Package: com.acme.foo;
company="ACME";
security=false
Attribute values are compared string wise except for the version and
bundle- version attributes which use version range comparisons.
3.6.6 Mandatory Attributes
There are two types of attributes: mandatory and optional. Mandatory
attributes must be specified in the import definition to match.
Optional attributes are ignored when they are not referenced by the
importer.Attributes are optional by default.
The exporter can specify mandatory attributes with the mandatory
directive in the export definition. This directive contains a
comma-separated list of attribute names that must be specified by the
importer to match.
For example, the following import definition must not match the export definition because security is a mandatory attribute:
这有两种属性类型:mandatory和optional。Mandatory属性必须在引入定义中指定用于匹配输出定义。Optional属性当引入者没有引用的时候被忽略。默认情况下属性是可选的。
输出者可以在输出定义中通过mandatory 指令来指定强制属性。这个指令包含了以逗号隔开的属性名的列表,它们必须被引入者指定用于匹配。
例如,下面的引入定义不能匹配输出定义,因为security是强制属性
A: Import-Package: com.acme.foo;company=ACME
B: Export-Package: com.acme.foo;
company="ACME";
security=false;
mandatory:=security
3.6.7 Class Filtering
An exporter can limit the visibility of the classes in a package with
the include and exclude directives on the export definition. The value
of each of these directives is a comma-separated list of class names.
Note that the use of a comma in the value requires it to be enclosed in
double quotes.
Class names must not include their package name and do not end with
.class. That is, the class com.acme.foo.Daffy is named Daffy in either
list. The class name can include multiple wildcards (’*’).
The default for the include directive is’*’ (wildcard matching all
names), and for the exclude directive, so that no classes or resources
are excluded, an empty list that matches no names. If include or
exclude directive are specified, the corresponding default is
overridden.
A class is only visible if it is:
• Matched with an entry in the included list, and
• Not matched with an entry in the excluded list.
一个输出者能在输出定义中通过include和exclude指令限制一个包中的类的可见性。这两个指令的值都是以逗号分隔的类名列表。注意值中逗号的使用,它需要被双引号括起来。
类名必须包含他们的包名并且不以.class结尾。也就是说,com.acme.foo.Daffy是是其中一个列表中名为Daffy的对象。类名也可以包含多个通配符('*')。
include指令的默认值是'*',对于exclude指令来说是空列表,匹配空名,因此没有类或资源被拒绝。如果yinclude或exclude指令被指定,相应的默认值要被重载。
一个类仅仅只能因下列因素而可见:
• 匹配include列表中的实体,并且
• 不匹配exclude列表中的实体
In all other cases, loading or finding fails, and a Class Not Found
Exception is thrown for a class load. The ordering of include and
exclude is not significant.
The following example shows an export statement, and a list of files with their visibility status.
否则,加载或寻找失败,并且抛出ClassNotFoundException。include和exclude的顺序没有特殊要求。
下面这个例子显示了一个输出声明,和一个文件列表以及它们的可见性状态。
Export-Package: com.acme.foo;
include:="Qux*,BarImpl";
exclude:=QuxImpl
com/acme/foo
QuxFoo visible
QuxBar visible
QuxImpl excluded
BarImpl visible
Care must be taken when using filters. For example, a new version of a
module that is intended to be backward compatible with an earlier
version should not filter out classes or resources that were not
filtered out by the earlier version. In addition, when modularizing
existing code, filtering out classes or resources from an exported
package may break users of the package.
For example, packages defined by standard bodies often require an
implementation class in the standardized package to have package access
to the specification classes.
使用过滤器的时候必须注意,例如,一个具有向下兼容的新版本模块,不应该过滤掉那些没有被前面的版本过滤掉的类或资源。另外,将现有代码模块化,从一个输出包中过滤类或资源可能会打断包的使用者。
例如,标准结构定义的包经常会需要一个标准包中的实现类,用于访问规范类。
package org.acme.open;
public class Specified {
static Specified implementation;
public void foo() {
implementation.foo();
}
}
package org.acme.open;
public class Implementation {
public void initialize(Specified implementation) {
Specified.implementation = implementation;
}
}
The Implementation class must not be available to external bundles
because it allows the implementation to be set. By excluding the
Implementation class, only the exporting bundle can see this class. The
export definition for this header could look like:
类Implementation必须对外部bundles不可用,因为它允许implementation被设置。通过拒绝类Implementation,仅仅只有输出bundle能看见它,输出定义可以这样:
Export-Package: org.acme.open; exclude:=Implementation
3.6.8 Provider Selection
Provider selection allows the importer to select which bundles can be
considered as exporters. Provider selection is used when there is no
specification contract between the importer and the exporter. The
importer tightly couples itself to a specific exporter, typically the
bundle that was used for testing. To make the wiring less brittle, the
importer can optionally specify a
range of bundle versions that will match.
An importer can select an exporter with the import attributes
bundlesymbolic- name and bundle-version. The Framework automatically
provides these attributes for each export definition. These attributes
must not be specified in an export definition.
The export definition bundle-symbolic-name attribute will contain the
bundle symbolic name as specified in the Bundle-SymbolicName header
without any parameters. The export definition bundle-version attribute
is set to the value of the Bundle-Version header or its default of
0.0.0 when absent.
The bundle-symbolic-name is matched as an attribute. The bundle-version
attribute is matched using the version range rules as defined in
Version Ranges on page 28. The import definition must be a version
range and the export definition is a version.
For example, the following definitions will match:
Provider selection允许引入者选择哪个bundle可以被认为是输出者。
Provider selection用于当引入者与输出者之间没有规范约定的时候。引入者严密的将自己连接到指定的输出者,特别是在测试的时候。为了放宽连接,引入者能指定一个bundle版本的范围来匹配。
引入者能通过属性bundle-symbolic- name和bundle-version选择一个输出者。框架自动为每一个输出定义提供这些属性。但是这些属性必须不能被指定在输出定义中。
输出定义bundle-symbolic-name属性将包含不含其它参数,指定在头Bundle-SymbolicName中的bundle标记名。输出定义bundle-version是头Bundle-Version的值或默认值0.0.0
bundle-symbolic-name作为一个属性被匹配,bundle-version使用版本范围规则来匹配。引入定义必须是一个版本范围,输出定义必须是一个版本值。
例如,下面的定义会被匹配:
A: Bundle-SymbolicName: A
Import-Package: com.acme.foo;
bundle-symbolic-name=B;
bundle-version="[1.41,2.0.0)"
B: Bundle-SymbolicName: B
Bundle-Version: 1.41
Export-Package: com.acme.foo
The following statements will not match because B does not specify a version and thus defaults to 0.0.0:
下面的声明不会被匹配,因为B没有指定版本,而是使用默认值0.0.0
A: Bundle-SymbolicName: A
Import-Package: com.acme.foo;
bundle-symbolic-name=B;
bundle-version="[1.41,2.0.0)"
B: Bundle-SymbolicName: B
Export-Package: com.acme.foo;version=1.42
Selecting an exporter by symbolic name can result in brittleness
because of hard coupling of the package to the bundle. For example, if
the exporter eventually needs to be refactored into multiple separate
bundles, all importers must be changed. Other arbitrary matching
attributes do not have this disadvantage as they can be specified
independently of the exporting bundle.
The brittleness problem of the bundle symbolic name in bundle
refactoring can be partly overcome by writing a facade bundle using the
same bundle symbolic name as the original bundle.
通过标记名来选择一个输出者会得到一个比较模糊的结果,因为对于bundle来说是硬连接。例如,如果一个输出者最终需要被重构成多个bundles,所有的引入者必须被修改。其他专有匹配属性就没有这个缺点,因为它们能被独立指定到输出bundle。
在重构中,bundle标记名的模糊问题,可以通过写一个具有相同标记名的门户bundle作为原先的那个bundle来分成几块解决。
转自:http://www.blogjava.net/Phrancol/articles/189711.html