gembin

          OSGi, Eclipse Equinox, ECF, Virgo, Gemini, Apache Felix, Karaf, Aires, Camel, Eclipse RCP

          HBase, Hadoop, ZooKeeper, Cassandra

          Flex4, AS3, Swiz framework, GraniteDS, BlazeDS etc.

          There is nothing that software can't fix. Unfortunately, there is also nothing that software can't completely fuck up. That gap is called talent.

          About Me

           

          OSGi Service Platform Core Specification Release 4 - Module Layer ( Part I 3.7-)

          3.7 Resolving Process

          Resolving is the process that creates a wiring between bundles. Constraints on the wires are statically defined by:
          • Import and export packages (the DynamicImport-Package header is ignored in this phase)
          • Required bundles, which import all exported packages from a bundle as defined in Requiring Bundles on page 65.
          • Fragments, which provide their contents and definitions to the host as defined in Fragment Bundles on page 68
          解析是bundle間建立連接的過程。連接上的約束的定義來自:
          • 引入和輸出包(頭DynamicImport-Package在這個階段被忽略)
          • Required bundles,從一個bundle那引入所有輸出包
          • 片段,提供它們的內容和定義到宿主bundle。

          Before a bundle is resolved, all its Fragments must be attached. The resolving process is then a constraint-solving algorithm that can be described in terms of requirements on wiring relations. The resolving process is an iterative process that searches through the solution space.

          If a module has both import and export definitions for the same package, then the Framework needs to decide which to choose. It must first try to resolve the overlapping import definition. The following outcomes are possible:
          • External – If this resolves to an export statement in another bundle, then the overlapping export definition in this bundle is discarded.
          • Internal – If it is resolved to an export statement in this module, then the overlapping import definition in this module is discarded.
          • Unresolved – There is no matching export definition. This is however a developer error because it means the overlapping export definition of the bundle is not compatible with the overlapping import definition.
          bundle被解析之前,它所有的片段必須被附加上。這時解析過程則是一個根據連接關系需求描述成的解析約束法則。解析過程是個搜索溶解空間的交互過程。
          如果一個模塊對同一個包都有引入和輸出定義,框架需要決定選擇哪一個定義,必須首先嘗試解析多重引入定義??赡軙幸韵陆Y果:
          • External – 如果將其解析到(選擇)另一個bundle的輸出聲明,那么這個bundle的多重輸出聲明將被放棄。
          • Internal – 如果他被解析到(選擇)當前bundle的輸出定義,那么這個多重引入定義被放棄。
          • Unresolved – 沒有匹配的輸出定義。這是開發者的錯誤,因為它表示這個bundle的多重輸出定義與多重引入定義不一致(同一個模塊下,一個包的引入定義找不到本模塊聲明的輸出定義)。

          A bundle can be resolved if the following conditions are met:
          • All its mandatory imports are wired
          • All its mandatory required bundles are available and their exports wired A wire is only created when the following conditions are met:
          • The importer’s version range matches the exporter’s version. See Version Matching on page 41.
          • The importer specifies all mandatory attributes from the exporter. See Mandatory Attributes on page 45.
          • All the importer’s attributes match the attributes of the corresponding exporter. See Attribute Matching on page 45
          • Implied packages referring to the same package as the wire are wired to the same exporter. See Package Constraints on page 43.
          • The wire is connected to a valid exporter.
          The following list defines the preferences, if multiple choices are possible, in order of decreasing priority:
          • A resolved exporter must be preferred over an unresolved exporter.
          • An exporter with a higher version is preferred over an exporter with a lower version.
          • An exporter with a lower bundle ID is preferred over a bundle with a higher ID.
          如果滿足以下條件,一個bundle會被解析:
          • 它所有的強制引入被連接
          • 它的強制需求bundles都可用,并且這些bundles的輸出連接A的連接當滿足以下條件時被創建:
          • 引入者的版本范圍匹配輸出者的版本
          • 引入者指定了所有輸出定義的強制屬性
          • 所有引入者的屬性匹配相應的輸出者的屬性
          • 暗指包引用同一個包,連接被連接到同一個輸出者。
          • 連接被連接到可用的輸出者
          如果多個選擇可用時,下面的列表定義了優先權,優先權順序遞減
          • 一個解析的輸出者必須優先于未解析輸出者
          • 一個版本高的輸出者優先于低版本
          • 低ID的bundle優先于高ID的bundle

          3.8 Runtime Class Loading

          Each bundle installed in the Framework must not have an associated class loader until after it is resolved. After a bundle is resolved, the Framework must create one class loader for each bundle that is not a fragment. The framework may delay creation of the class loader until it is actually needed.
          One class loader per bundle allows all resources within a bundle to have package level access to all other resources in the bundle within the same package. This class loader provides each bundle with its own name space, to avoid name conflicts, and allows resource sharing with other bundles.
          This class loader must use the wiring as calculated in the resolving process to find the appropriate exporters. If a class is not found in the imports, additional headers in the manifest can control the searching of classes and resources in additional places.
          The following sections define the factors that influence the runtime class loading and then define the exact search
          安裝在框架中的每一個bundle必須不能有一個關聯的class loader,直到這個bundle被解析之后。一個bundle被解析之后,框架必須為每一個bundle創建一個class loader,而不是片段??蚣芸赡軙舆tclass loader的生成,直到它真正被需要。
          一個bundle的class loader允許這個bundle中所有的資源得到對其他所有這個bundle中同一個package中的資源的包級別訪問權限。這個class loader為bundle提供它自己的名字空間,用于避免名字沖突,允許資源共享到其他bundles。
          class loader必須使用與在解析過程中一樣的連接去查找合適的輸出者。如果一個類在引入者中找不到,manifest中附加的頭可以控制在附加的空間中對類和資源的查找。
          一下章節定義了影響運行時類加載的因素,然后定義了精確查找

          3.8.1 Bundle Class Path

          Intra bundle class path dependencies are declared in the Bundle-Classpath manifest header. This declaration allows a bundle to declare its embedded class path using one or more JAR files or directories that are contained in the bundle’s JAR file.
          The Bundle-Classpath manifest header is a list of comma-separated file names. A file name can be either:
          • The dot (’.’ \u002E), representing the bundle’s JAR file itself, is the default value if no Bundle-Classpath is specified.
          • A path to a JAR file contained in the bundle’s JAR file.
          • A path to a directory contained in the bundle’s JAR file.
          The Bundle-Classpath manifest header must conform to the following syntax:
          bundle內部的類路徑依賴關系被聲明在manifest頭Bundle-Classpath中。這個聲明允許一個bundle使用一個或多個包含在bundle的JAR文件中的JAR文件或目錄去聲明它的內部的類路徑。
          頭Bundle-Classpath是一個逗號分隔的文件名列表。一個文件名可以是以下內容:
          • 點,描述bundle的JAR文件自己,默認值。
          • 包含在bundle的JAR文件中的一個JAR文件路徑
          • 包含在bundle的JAR文件中的一個目錄的路徑
          頭Bundle-Classpath必須符合下面的語法:
          Bundle-Classpath::= entry ( ’,’ entry )*
          entry ::= target ( ’;’ target )*
          ( ’;’ parameter ) *
          target ::= path | ’.’ // See 1.3.2
          The Framework must ignore any unrecognized parameters.
          The Framework must ignore a target in the Bundle-Classpath header if the target (directory or JAR file) cannot be located when it is needed, which can happen at any time after the bundle is resolved. However, in this case the Framework should publish a Framework Event of type INFO with an appropriate message for each entry that cannot be located.
          When locating a class path entry in a bundle, the Framework must attempt to locate the class path entry relative to the root of the bundle’s JAR. If a class path entry cannot be located in the bundle, then the Framework must attempt to locate the class path entry in each of the attached fragment bundles.
          The attached fragment bundles are searched in ascending bundle ID order. This allows a fragment to supply entries that are inserted into the host's Bundle-Classpath
          The following example illustrates this:
          框架必須忽略所有未經承認的參數。
          框架必須忽略頭Bundle-Classpath中的target,如果當需要的時候這個target(目錄或JAR文件)不能被找到,這個忽略可以發生 在bundle被解析后的任何時間。盡管如此,在這種情況下,框架應該發布一個類型為INFO的事件,為每一個不能定位的entry生成一條合適的消息。
          當在bundle中定位一個類路徑實體的時候,框架必須嘗試定位相對于bundle的JAR文件的根路徑的類路徑實體。如果在bundle一個類路徑不能被定位,那么框架必須嘗試定位每一個附加片段bundles中的類路徑實體。
          附加片段bundles通過bundle ID的升序來查找。這就允許了片段提供宿主bundle的頭Bundle-Classpath中插入的實體。
          請看下面是個例子:
          A: Bundle-SymbolicName: A
          Bundle-Classpath: required.jar,optional.jar,default.jar
          content 
          required.jar
          default.jar
          B: Bundle-SymbolicName: B
          Bundle-Classpath: fragment.jar
          Fragment-Host: A
          content 
          optional.jar
          fragment.jar
          In this example, bundle A has a Bundle-Classpath header with three entries (required.jar, optional.jar, and default.jar). The required.jar class path entry may contain the classes and resources that must be present for the bundle to function. The optional.jar class path entry may contain classes and resources that the bundle will use if present.

          The default.jar class path entry may contain classes and resources that the bundle will use if the optional.jar is not available, but the classes and resources from default.jar can be overridden by classes and resources in the optional.jar (from the fragment) class path entries. Bundle A has only the required.jar and default.jar entries packaged with it. This allows a fragment bundle B to be installed that can supply the optional.jar for bundle A.

          The fragment bundle B has a Bundle-Classpath with one entry (fragment. jar). When bundle A is resolved and the fragment bundle B is attached then the bundle class path for the bundle A is:
          在這個例子中,bundle A的頭Bundle-Classpath有3個實體(required.jar, optional.jar, and default.jar)。required.jar類路徑實體可能包含必須提供給bundle的功能的類和資源。optional.jar類路徑實體可 能包含如果提供,bundle會使用到的類和資源(例如logging)。
          default.jar類路徑實體可能包含如果optional.jar不可用,那么bundle可能會用到的類和資源,但是default.jar中的 類和資源能被optional.jar(片段bundle中)中的類和資源重載。bundle A中只打包了required.jar和default.jar實體,這允許片段bundle B被安裝,為bundle A提供optional.jar。
          片段bundle B頭Bundle-Classpath有一個實體(fragment. jar)。當bundle A被解析,片段bundle B被附加時,bundle A的類路徑則成為:
          required.jar, optional.jar, default.jar, fragment.jar

          3.8.2 Dynamic Import Package

          Dynamic imports are matched to export definitions (to form package wirings) during class loading, and therefore do not affect module resolution.
          Dynamic imports apply only to packages for which no wire has been established and no definition could be found in any other way. Dynamic import is used as last resort.
          動態引入在類加載期間被匹配到輸出定義(用于構成包連接),因此不會影響到模塊的解析。
          動態引入僅僅適用于沒有被連接和無法從其他方式獲得定義的包。動態引入是最后的手段。
          DynamicImport-Package ::= dynamic-description
          ( ',' dynamic-description )*
          dynamic-description::= wildcard-names ( ';' parameter )*
          wildcard-names ::= wildcard-name ( ';' wildcard-name )*
          wildcard-name ::= package-name
          | ( package-name '.*' ) // See 1.3.2
          | '*'

          No directives are architected by the Framework for DynamicImport-Package.
          Arbitrary matching attributes may be specified. The following arbitrary matching attributes are architected by the Framework:
          • version -- A version range to select the version of an export definition. The default value is 0.0.0 .
          • bundle-symbolic-name – The bundle symbolic name of the exporting bundle.
          • bundle-version – a version range to select the bundle version of the exporting bundle. The default value is 0.0.0.

          Packages may be named explicitly or by using wild-carded expressions such as org.foo.* and *. The wildcard can stand for any suffix, including multiple sub-packages.

          Dynamic imports must be searched in the order in which they are specified.
          The order is particularly important when package names with wildcards are used. The order will then determine the order in which matching occurs.
          This means that the more specific package specifications should appear before the broader specifications. For example, the following DynamicImport- Package header indicates a preference for packages supplied by ACME:
          框架不必為DynamicImport-Package創建指令,可以指定專有匹配屬性,一下專有匹配屬性由框架給定:
          • version -- 一個版本范圍,用于選擇輸出定義的版本。默認值是0.0.0
          • bundle-symbolic-name – 輸出bundle的標記名
          • bundle-version – 一個版本范圍,用于選擇輸出bundle的版本。默認值是0.0.0
          packages能被明確指定,或使用通配符表達式,它能代替任何后綴,包括多個sub-packages。

          動態引入必須在指定的順序下查找包。
          當包名使用的是通配符時,這個順序顯得尤為重要。這時,這個順序將決定發生匹配的順序。
          也就是說指定的包規范應該更多的出現在擴展規范之前。例如,下面這個頭DynamicImport- Package表示優先選擇由ACME提供的包
          DynamicImport-Package: *;vendor=acme, *

          If multiple packages need to be dynamically imported with identical parameters, the syntax permits a list of packages, separated by semicolons, to be specified before the parameters.

          During class loading, the package of the class being loaded is compared against the specified list of (possibly wild-carded) package names. Each matching package name is used in turn to attempt to wire to an export using the same rules as Import-Package. If a wiring attempt is successful (taking any uses constraints into account), the search is forwarded to the exporter’s class loader where class loading continues. The wiring must not subsequently be modified, even if the class cannot be loaded. This implies that once a package is dynamically resolved, subsequent attempts to load classes or resources from that package are treated as normal imports.
          如果多個包需要被以相同的參數引入,這個語法允許一個包列表,以分號隔開,指定在參數之前。
          類加載期間,被加載的類的包被與指定的包名的列表(或通配符)比較,每一個匹配的包名輪流嘗試按照Import-Package的規則連接到一個輸出。如 果一個嘗試連接成功(按照uses約束),當繼續加載類時,查找會被定位到輸出者的class loader。之后,這個連接必須不能被更改,即使隨后的類不能被加載。也就是說一旦一個包是被動態解析的,那么隨后嘗試從這個包中加載類或資源將被視為 普通引入。
          In order for a DynamicImport-Package to be resolved to an export statement, all attributes of the dynamic import definition must match the attributes of the export statement. All mandatory arbitrary attributes (as specified by the exporter, see Mandatory Attributes on page 45) must be specified in the dynamic import definition and match.

          Once a wire is established, any uses constraints from the exporter must be obeyed for further dynamic imports.

          Dynamic imports are very similar to optional packages, see Optional Packages on page 42, but differ in the fact that they are handled after the bundle is resolved.
          為了使一個動態引入包被解析到一個輸出聲明,所有動態引入定義中的屬性必須匹配輸出聲明中的屬性,所有輸出聲明中的強制專有屬性必須在動態引入定義中指定并匹配。
          一旦一個連接被產生,輸出者中所有uses約束必須被動態引入者遵循。
          動態引入與可選包非常相似,但是實際上他們區別于bundle被解析之后才被處理。

          3.8.3 Parent Delegation

          The Framework must always delegate any package that starts with java. to the parent class loader.
          Certain Java virtual machines, also SUN’s VMs, appear to make the erroneous assumption that the delegation to the parent class loader always occurs. This implicit assumption of strictly hierarchical class loader delegation can result in NoClassDefFoundErrors. This happens if the virtual machine implementation expects to find its own implementation classes from any arbitrary class loader, requiring that packages loaded from the boot class loader not be restricted to only the java.* packages.
          Other packages that must be loaded from the boot class loader can therefore be specified with the System property:
          框架必須總是代理以java開頭的包到parent class cloader。
          顯然JVM做了一個錯誤的假設,到parent class cloader的代理總是會發生。而這個嚴格等級的class loader代理的所隱藏的假設,會導致NoClassDefFoundErrors。如果虛擬機實現希望從所有專有class loader中查找它自己的實現類,它需要的包是從boot class loader中加載的,而不僅僅局限于java.*這樣的包。
          因此,其他必須從boot class loader加載的包能被指定到以下系統屬性:
          org.osgi.framework.bootdelegation

          This property must contain a list with the following format:
          org.osgi.framework.bootdelegation ::= boot-description
          ( ',' boot-description )*
          boot-description::= package-name // See 1.3.2
          | ( package-name '.*' )
          | '*'

          The .* wildcard means deep matching. Packages that match this list must be loaded from the parent class loader. The java.* prefix is always implied; it does not have to be specified.
          The single wildcard means that the Framework must always delegate to the parent class loader first, which is the same as the Release 3 behavior. For example, when running on a SUN JVM, it may be necessary to specify a value like:
          通配符.*表示深層匹配。匹配這個列表的包必須被從parent class loader中加載。前綴java.*總是隱含著;而不需要指定。單個通配符表示框架必須總是首先代理到parent class loader,與版本3一樣。例如,當運行于sun jvm時,它可能有必要指定一個如下的值:
          org.osgi.framework.bootdelegation=sun.*,com.sun.*

          With such a property value, the Framework must delegate all java.*, sun.*, and com.sun.* packages to the parent class loader.
          對于這樣的值,框架必須代理所有java.*, sun.*, 和 com.sun.*的包到parent class loader。

          3.8.4 Overall Search Order

          Frameworks must adhere to the following rules for class or resource loading. When a bundle’s class loader is requested to load a class or find a resource, the search must be performed in the following order:
          框架必須遵循以下規則來加載類或資源。當一個bundle的class loader被請求加載類或查找資源時,必須按照以下順序來執行:

          1 If the class or resource is in a java.* package, the request is delegated to the parent class loader; otherwise, the search continues with the next step. If the request is delegated to the parent class loader and the class or resource is not found, then the search terminates and the request fails.
          1. 如果類或資源在一個java.*的包中,這個請求被代理到parent class loader,否則,進入下一步。如果請求被代理到parent class loader,而類或資源卻沒有找到,那么查找被中斷,請求失敗。

          2 If the class or resource is from a package included in the boot delegation list (org.osgi.framework.bootdelegation), then the request is delegated to the parent class loader. If the class or resource is found there, the search ends.
          2. 如果類或資源來自一個包含在boot代理列表中的包,那么這個請求被代理到parent class loader。如果類或資源被找到,那么請求結束。

          3 If the class or resource is in a package that is imported using Import-Package or was imported dynamically in a previous load, then the request is delegated to the exporting bundle’s class loader; otherwise the search continues with the next step. If the request is delegated to an exporting class loader and the class or resource is not found, then the search terminates and the request fails.
          3. 如果類或資源是在一個使用Import-Package引入,或是前面的加載中動態引入的包中,那么請求將被代理到輸出bundle的class loader。否則進入下一步。如果請求被代理到一個輸出bundle的class loader,類或資源沒有找到,那么查找中斷,請求失敗。

          4 If the class or resource is in a package that is imported from one or more other bundles using Require-Bundle, the request is delegated to the class loaders of the other bundles, in the order in which they are specified in this bundle’s manifest. This entails a depth-first strategy; all required bundles are searched before the bundle classpath is used. If the class or resource is not found, then the search continues with the next step.
          4. 如果類或資源是在一個使用Require-Bundle從一個或多個其他bundles引入的包中,這個請求將被代理到這些bundles的class loader,按照manifest中指定的順序。這確保了深度優先策略;所有required bundles在bundle類路徑使用之前被查找。如果類或資源沒有找到,進入下一步。

          5 The bundle’s own internal bundle class path is searched. If the class or resource is not found, then the search continues with the next step.
          5. 查找bundle自己的內部類路徑。如果資源或類沒有找到,進入下一步。

          6 Each attached fragment’s internal bundle class path is searched. The fragments are searched in ascending bundle ID order. If the class or resource is not found, then the search continues with the next step.
          6. 查找附加片段的內部bundle類路徑,查找順序根據bundle ID的升序,如果沒有找到,進入下一步。

          7 If the class or resource is in a package that is exported by the bundle or the package is imported by the bundle (using Import-Package or Require-Bundle), then the search ends and the class or resource is not found.
          7. 如果類或資源是在一個被片段bundle輸出的包中,或者這個包被片段bundle(使用Import-Package or Require-Bundle)引入,那么查找終止,類或資源無法被找到。

          8 Otherwise, if the class or resource is in a package that is imported using DynamicImport-Package, then a dynamic import of the package is now attempted. An exporter must conform to any implied package constraints. If an appropriate exporter is found, a wire is established so that future loads of the package are handled in Step 3. If a dynamic wire is not established, then the request fails.
          8. 否則,如果類或資源是在一個使用DynamicImport-Package引入的包中,那么包的動態引入被附加。一個輸出者必須遵循所有的暗指包約束。 如果一個合適的輸出者被找到,一個連接被創建,然后包的加載在步驟3中被處理。如果一個動態連接沒有被創建,那么請求失敗。

          9 If the dynamic import of the package is established, the request is delegated to the exporting bundle’s class loader. If the request is delegated to an exporting class loader and the class or resource is not found, then the search terminates and the request fails.
          9. 如果包的動態引入被創建,請求被代理到輸出bundle(片段bundle)的class loader。如果類或資源沒有找到,查找失敗。

          When delegating to another bundle class loader, the delegated request enters this algorithm at Step 4.

          The following non-normative flow chart illustrates the search order described above:


          3.8.5 Parent Class Loader

          The set of implicitly imported packages are all java.* packages, since these packages are required by the Java runtime, and using multiple versions at the same time is not easy. For example, all objects must extend the same Object class.

          A bundle must not declare imports or exports for java.* packages; doing so is an error and any such bundle must fail to install. All other packages available through the parent class loader must be hidden from executing bundles.
          However, the Framework must explicitly export relevant packages from the parent class loader.

          The system property
          暗指包是所有java.*包,因為這些包是JAVA運行所需。在同一時間使用多個版本并不容易,例如,所有的對象必須繼承同一個類Object
          一個bundle必須不能為包java.*聲明輸出或引入;這么做是一個錯誤并且凡是這樣做的bundle都必須安裝失敗。所有其他對parent class loader可用的包必須被隱藏到執行bundles。
          可是,框架必須輸出parent class loader相關的包。

          系統屬性
          org.osgi.framework.system.packages

          contains the export packages descriptions for the system bundle. This property employs the standard Export-Package manifest header syntax:
          包含了描述系統bundle的輸出包。它使用標準Export-Package頭語法
          org.osgi.framework.system.packages ::= package-description (
          ',' package-description )*

          Some classes on the boot class path assume that they can use any class loader to load other classes on the boot class path, which is not true for a bundle class loader. Framework implementations should attempt to load these classes from the boot class path.

          The system bundle (bundle ID zero) is used to export non-java.* packages from the parent class loader. Export definitions from the system bundle are treated like normal exports, meaning that they can have version numbers, and are used to resolve import definitions as part of the normal bundle resolving process. Other bundles may provide alternative implementations of the same packages.

          The set of export definitions for the parent class loader can either be set by this property or calculated by the Framework. The export definitions must have the implementation specific bundle symbolic name and version value of the system bundle.

          Exposing packages from the parent class loader in this fashion must also take into account any uses directives of the underlying packages. For example, the definition of javax.crypto.spec must declare its usage of javax.crypto.interfaces and javax.crypto.
          一些boot class path中的類假設為他們可以使用任何class loader去加載boot class path中的其他類,對于一個bundle的class loader這時不對的??蚣軕搰L試從boot class path加載這些類。
          系統bundle(ID是0)用于從parent class loader中輸出非java.*的包。系統bundle中的輸出定義被視為常規輸出,也就是說它們能有版本號,用于解析引入定義,作為常規解析的一部 分。其他bundles可以提供對同一個包作為選擇的實現。
          parent class loader的輸出定義能被這個屬性設置或是通過框架決定。輸出定義必須有實現系統bundle的特定bundle標記名和版本號。
          通過這個方式從parent class loader中暴露(輸出)的包必須考慮到這些包的uses指令。例如,javax.crypto.spec的定義必須聲明它的javax.crypto.interfaces 和 javax.crypto.的用法

          3.8.6 Resource Loading

          A resource in a bundle can be accessed through the class loader of that bundle but it can also be accessed with the getResource, getEntry or findEntries methods. All these methods return a URL object or an Enumeration object of URL objects. The URLs are called bundle entry URLs. The schemes for the URLs returned by these methods can differ and are implementation dependent.

          Bundle entry URLs are normally created by the Framework, however, in certain cases bundles need to manipulate the URL to find related resources. The Framework is therefore required to ensure that:
          一個bundle中的資源可以通過這個bundle的class loader,它同樣能被方法getResource, getEntry 或 findEntries訪問到。所有這些方法都返回一個URL對象或一個URL對象的Enumeration對象。URLs 被稱為bundle實體URLs。
          bundle實體URLs通常是由框架生成,但是無論如何都是通過操作URL找到相關資源。因此框架需要確保:
          • Bundle entry URLs must be hierarchical (See [32] Uniform Resource Identifiers URI: Generic Syntax)
          • Usable as a context for constructing another URL.
          • The java.net.URLStreamHandler class used for a bundle entry URL must be available to the java.net.URL class to setup a URL that uses the protocol scheme defined by the Framework.
          • The getPath method for a bundle entry URL must return an absolute path (a path that starts with '/') to a resource or entry in a bundle. For example, the URL returned from getEntry("myimages/test.gif") must have a path of /myimages/test.gif.
          • bundle實體URLs必須是分等級的。
          • 對構造其他URL的context可用。
          • 使用于bundle entry URL的類java.net.URLStreamHandler必須對類java.net.URL可用,用于設置一個使用框架定義的協議摘要的URL。
          • 用于一個bundle entry URL的方法getPath必須返回一個bundle中的資源或實體的絕對路徑,

          For example, a class can take a URL to an index.html bundle resource and map URLs in this resource to other files in the same JAR directory.

          public class BundleResource implements HttpContext {
            URL root; 
          // to index.html in bundle
            URL getResource( String resource ) {
              
          return new URL( root, resource );
            }
            
          }

          3.8.7 Bundle Cycles

          Multiple required bundles can export the same package. Bundles which export the same package involved in a require bundle cycle can lead to lookup cycles when searching for classes and resources from the package.

          Consider the following definitions:
          多個必須的bundle能輸出同一個包。輸出同一個包的bundles包含了一個bundle循環,能循環查找包中的類和資源。
          考慮下面的定義
          A: Require-Bundle: B, C
          C: Require-Bundle: D


          These definitions are depicted in Figure 3.19.

          Each of the bundles exports the package p. In this example, bundle A requires bundle B, and bundle C requires bundle D. When bundle A loads a class or resource from package p, then the required bundle search order is the following: B, D, C, A. This is a depth first search order because required bundles are searched before the bundle classpath is searched (see step 4).

          The required bundles are searched in the order that they appear in the Require-Bundle header. The depth first search order can introduce endless search cycles if the dependency graph has a cycle in it.

          Using the previous setup, a cycle can be introduced if bundle D requires bundle A as depicted in Figure 3.20.
          他們都輸出包p。在這個例子中,bundle A需要bundle B,和C,bundle C需要bundle D.當bundle A從包p中加載一個類或資源時,查找順序則為:B,D,C,A. 這時一個深層有限查找順序,因為required bundles先于本bundle的classpath被查找。
          required bundles被查找的順序按照Require-Bundle頭中出現的順序。深層有限查找順序能陷入無限查找循環,如果里面的依賴圖是循環的話。

          D: Require-Bundle: A

          When the class loader for bundle A loads a class or resource from package p then the bundle search order would be the following: B, B, B,... if cycles were not taken into account.

          Since a cycle was introduced each time bundle D is reached the search will recurs back to A and start over. The framework must prevent such dependency cycles from causing endless recursive lookups.

          To avoid endless looping, the Framework must mark each bundle upon first visiting it and not explore the required bundles of a previously visited bundle. Using the visited pattern on the dependency graph above will result in the following bundle search order: B, D, C, A.
          當bundle A的class loader從包p加載一個類或資源時,bundle查找順序將變成:B,B,B,...如果不考慮循環。
          因為每次循環到bundle D的時候,查找將會返回到A并重新開始??蚣鼙仨毞乐惯@種依賴循環導致的無限遞歸查找。
          要避免無限循環,框架必須標記每個bundle第一次訪問,并且不會訪問先前訪問過的bundle的required bundles。 將這個模式使用在上面的依賴圖中,將是查找順序變為:B,D,C,A.

          3.8.8 Code Executed Before Started

          Packages exported from a bundle are exposed to other bundles as soon as the bundle has been resolved. This condition could mean that another bundle could call methods in an exported package before the bundle exporting the package is started.
          一旦一個bundle被解析,它輸出的包將暴露給其他bundles。也就是說輸出了包的bundle啟動之前,其他bundle就能調用這個包中的方法了。

          3.9 Loading Native Code Libraries

          When a class loaded by a bundle's class loader attempts to load a native library, by calling System.loadLibrary, the findLibrary method of the bundle’s class loader must be called to return the file path in which the Framework has made the requested native library available. The parameter to the findLibrary method is the name of the library in operating system independent form, like http. The bundle class loader can use the mapLibraryName method from the VM to map this name to an operating system dependent name, like libhttp.so.
          當一個被bundle的class loader加載了的類嘗試使用System.loadLibrary加載本地庫時,bundle的class loader的findLibrary方法必須被調用,用于返回文件路徑,框架已經使其可用。findLibrary方法的參數是操作系統中獨立庫的名 字,例如http。這個bundle的class loader可以使用VM的方法mapLibraryName將這個名字映射到由操作系統決定的名字,就像libhttp.so。

          The bundle's class loader must attempt to find the native library by examining the selected native code clauses, if any, of the bundle associated with the class loader and each attached fragment. Fragments are examined in ascending bundle ID order. If the library is not referenced in any of the selected native code clauses then null must be returned which allows the parent class loader to search for the native library.

          The bundle must have the required RuntimePermission[loadLibrary.<library name>] in order to load native code in the OSGi Service Platform.

          The Bundle-NativeCode manifest header must conform to the following syntax:
          Bundle-NativeCode ::= nativecode
          ( ',' nativecode )* ( ’,’ optional) ?
          nativecode ::= path ( ';' path )* // See 1.3.2
          ( ';' parameter )+
          optional ::= ’*’

          When locating a path in a bundle the Framework must attempt to locate the path relative to the root of the bundle that contains the corresponding native code clause in its manifest header.

          The following attributes are architected:
          • osname – Name of the operating system. The value of this attribute must be the name of the operating system upon which the native libraries run. A number of canonical names are defined in Environment Properties on page 93.
          • osversion – The operating system version. The value of this attribute must be a version range as defined in Version Ranges on page 28.
          • processor – The processor architecture. The value of this attribute must be the name of the processor architecture upon which the native libraries run. see Environment Properties on page 93.
          • language – The ISO code for a language. The value of this attribute must be the name of the language for which the native libraries have been localized.
          • selection-filter – A selection filter. The value of this attribute must be a filter expression that indicates if the native code clause should be selected or not.

          The following is a typical example of a native code declaration in a bundle's manifest:
          Bundle-NativeCode: lib/http.dll ; lib/zlib.dll ;
          osname = Windows95 ;
          osname = Windows98 ;
          osname = WindowsNT ;
          processor = x86 ;
          selection-filter=
          "(com.acme.windowing=win32)";
          language = en ;
          language = se ,
          lib/solaris/libhttp.so ;
          osname = Solaris ;
          osname = SunOS ;


          3.10 Localization

          A bundle contains a significant amount of information that is human-readable. Some of this information may require different translations depending on the user's language, country, and any special variant preferences, a.k.a. the locale. This section describes how a bundle can provide common translations for the manifest and other configuration resources depending on a locale.

          Bundle localization entries share a common base name. To find a potential localization entry, an underscore (’_’ \u005F) is added plus a number of suffixes, separated by another underscore, and finally appended with the suffix .properties . The suffixes are defined in java.util.Locale.

          The order for the suffixes this must be:
          • language
          • country
          • variant

          For example, the following files provide manifest translations for English, Dutch (Belgium and the Netherlands) and Swedish.
          一個bundle包含一個長幅的可讀性信息。這些信息可能需要根據用戶語言,國家和任何指定的變量參數(也叫做locale)的不同來進行轉換。本節描述了一個bundle怎樣根據一個locale來提供一個普通的轉換給manifest和其他配置資源。

          bundle本地化實體共享一個基本的普通名字。要找到潛在的本地化實體,會有一個下劃線加上一個后綴,由另一個下劃線分隔,最終以后綴.properties結束。這個后綴定義在java.util.Locale。

          OSGI-INF/l10n/bundle_en.properties
          OSGI-INF/l10n/bundle_nl_BE.properties
          OSGI-INF/l10n/bundle_nl_NL.properties
          OSGI-INF/l10n/bundle_sv.properties

          The Framework searches for localization entries by appending suffixes to the localization base name according to a specified locale and finally appending the .properties suffix. If a translation is not found, the locale must be made more generic by first removing the variant, then the country and finally the language until an entry is found that contains a valid translation.
          框架查找本地化實體,通過根據指定的locale 添加后綴到本地化基礎名,最后添加后綴.properties。如果一個轉換沒有找到,locale必須通過刪除第一個變量,接著是國家,最后是語言,從而變得更通用,直到一個包含了可用轉換的實體被發現。

          For example, looking up a translation for the locale en_GB_welsh will search in the following order:
          例如,查找順序如下:

          OSGI-INF/l10n/bundle_en_GB_welsh.properties
          OSGI-INF/l10n/bundle_en_GB.properties
          OSGI-INF/l10n/bundle_en.properties
          OSGI-INF/l10n/bundle.properties

          This allows localization files for more specific locales to override localizations from less specific localization files.

          3.10.1 Finding Localization Entries

          Localization entries can be contained in the bundle or delivered in fragments. The Framework must therefore first look in the bundle and then in its attached fragments. Fragment bundles must delegate the search for a localization entry to their host bundle with the lowest bundle ID.

          The bundle's class loader is not used to search for localization entries. Only the contents of the bundle and its attached fragments are searched. The bundle will still be searched for localization entries even if dot ('.') is not in the bundle class path.

          本地化實體可以被包含在bundle中,或放在片段中。因此框架必須首先查看bundle,然后再看它的片段。片段bundle必須代理它的最小ID的宿主bundle對本地化實體的查找。
          bundle的class loader不是用來查找本地化實體的。僅僅是bundle的內容和它的片段被查找。即使.不在bundle的類路徑中,bundle將仍然會被查找本地化實體。

          3.10.2 Manifest Localization

          Localized values are stored in property resources within the bundle. The default base name of the bundle localization property files is OSGI-INF/l10n/bundle. The Bundle-Localization manifest header can be used to override the default base name for the localization files. This location is relative to the root of the bundle and bundle fragments.

          A localization entry contains key/value entries for localized information. All headers in a bundle's manifest can be localized. However, the Framework must always use the non-localized versions of headers that have Framework semantics.

          A localization key can be specified as the value of a bundle's manifest header using the following syntax:
          本地值被保存在bundle中的屬性資源中。bundle本地化屬性文件的默認基礎名是OSGI-INF/l10n/bundle。頭Bundle-Localization用于重載這個默認值,路徑是相對于bundle和片段bundle的根路徑。
          一個本地化實體包含用于本地信息的key/value實體。manifest中所有的頭都能被本地化。然而,框架必須始終使用含有框架語義的頭的非本地化版本。
          使用以下語法指定manifest頭中的本地化值
          header-value ::= ’%’text
          text ::= 
          < any value which is both a valid manifest header value and a valid property key name >

          For example, consider the following bundle manifest entries:

          Bundle-Name: %acme bundle
          Bundle-Vendor: %acme corporation
          Bundle-Description: %acme description
          Bundle-Activator: com.acme.bundle.Activator
          Acme-Defined-Header: %acme special header

          User-defined headers can also be localized. Spaces in the localization keys are explicitly allowed.
          用戶定義的頭也能被本地化。本地化KEY是可以包含空格的

          The previous example manifest entries could be localized by the following entries in the manifest localization entry OSGI-INF/l10n/bundle.properties.

          # bundle.properties
          acme\ bundle=The ACME Bundle
          acme\ corporation=The ACME Corporation
          acme\ description=The ACME Bundle provides all of the ACME \services
          acme\ special header=user-defined Acme Data

          The above manifest entries could also have French localizations in the manifest localization entry OSGI-INF/l10n/bundle_fr_FR.properties.

          3.11 Bundle Validity

          If the Bundle-ManifestVersion is not specified, then the bundle manifest version defaults to 1, and certain Release 4 syntax, such as a new manifest header, is ignored rather than causing an error. Release 3 bundles must be treated according to the R3 specification.
          如果Bundle-ManifestVersion沒有被指定,那么將被設置成默認值1,對于版本4的語法,像這種新manifest頭,將被忽略,而不是拋出錯誤。版本3的bundle必須根據版本3規范使用。
          The following (non-exhaustive) list of errors causes a bundle to fail to install:
          下面的錯誤列表會使bundle安裝失?。?br /> • Bundle-RequireExecutionEnvironment header does not match the available execution environments.
          • 頭Bundle-RequireExecutionEnvironment不匹配可用的執行環境
          • Missing Bundle-SymbolicName.
          • 缺少頭Bundle-SymbolicName
          • Duplicate attribute or duplicate directive (except in the Bundle-Native code clause).
          • 多個屬性或指令
          • Multiple imports of a given package.
          • 對一個包的多次引入
          • Export or import of java.*.
          • 輸出或引入java.*
          • Export-Package with a mandatory attribute that is not defined.
          • Export-Package的強制屬性是沒有定義的(3.6.6關于強制屬性的定義)
          • Installing a bundle that has the same symbolic name and version as an already installed bundle.
          • 安裝一個bundle,與已經安裝的bundle具有相同的標記名和版本
          • Updating a bundle to a bundle that has the same symbolic name and version as another installed bundle.
          • 更新一個bundle,與已經安裝的bundle具有相同的標記名和版本
          • Any syntactic error (for example, improperly formatted version or bundle symbolic name, unrecognized directive value, etc.).
          • 任何語法錯誤(例如,不正確的版本和標記名格式,無效的的指令等)
          • Specification-version and version specified together (for the same package(s)) but with different values on manifest headers that treat them as synonyms. For example:
          • 為同一個包同時指定Specification-version和version相同的值。

          Import-Package p;specification-version=1;version=2

          would fail to install, but:
          Import-Package p;specification-version=1, q;version=2

          would not be an error.
          • The manifest lists a OSGI-INF/permission.perm file but no such file is present.
          • manifest指定了OSGI-INF/permission.perm文件,卻沒有這個文件存在。
          • Bundle-ManifestVersion value not equal to 2, unless the Framework specifically recognizes the semantics of a later release.
          • Bundle-ManifestVersion的值不等于2,除非框架明確給出后面的版本的語義

          3.12 Optional

          This specification provides for one optional mechanism: the boot class path extension. The reason to make this mechanism optional is that it is not possible to implement this in a portable way. A compliant framework must set the following property to true or false depending on the implementation of the boot class path extension:
          • org.osgi.supports.bootclasspath.extension

          If the property is not set or the value is unrecognized, then the value defaults to false. A Framework that does not implement the bootclasspath extension must refuse to install or update a bundle that carries this option. It must then throw an exception at install or update time.

          Additionally, frameworks must implement fragments, require bundle, and extensions. They must therefore set the following properties to true.

          這部分規范提供了一個可選機制:boot類路徑擴展。將這個機制做成可選的原因是它不可能很輕易被實現。一個適應性強的框架必須根據對boot類路徑擴展的實現來設置這個屬性的值為true或false。
          • org.osgi.supports.bootclasspath.extension
          如果這個屬性沒有設置,或沒有賦值,那么默認值為false。一個沒有實現bootclasspath extension的框架必須拒絕安裝或更新一個帶有這個選項的bundle。然后拋出一個exception。
          另外,框架必須實現fragments, require bundle, and extensions。因此一下屬性必須賦值為true:
          • org.osgi.supports.framework.requirebundle
          • org.osgi.supports.framework.fragments
          • org.osgi.supports.framework.extension

          3.13 Requiring Bundles

          The Framework supports a mechanism where bundles can be directly wired to other bundles. The following sections define the relevant headers and then discuss the possible scenarios. At the end, some of the (sometimes unexpected) consequences of using Require-Bundle are discussed.
          框架支持bundle直接連接到另外的bundle機制。一下章節定義了相關的頭,然后討論可能的假設。最后,討論一些使用Require-Bundle的結果。

          3.13.1 Require-Bundle

          The Require-Bundle manifest header contains a list of bundle symbolic names that need to be searched after the imports are searched but before the bundle’s class path is searched. Fragment or extension bundles can not be required. Only packages that are marked exported by the required bundles are visible to the requiring bundle.
          The Require-Bundle manifest header must conform to the following syntax:
          頭Require-Bundle包含了bundle標記名的列表,這些標記名需要在引入查找之后,bundle類路徑查找之前被查找。片段或擴展不是必須的。只有被 required bundles標記為輸出的包材對requiring bundle可見。

          Require-Bundle ::= bundle-description( ',' bundle-description )*
          bundle-description ::= symbolic-name // See 1.3.2(';' parameter )*

          The following directives can be used in the Require-Bundle header:
          以下指令可以用在頭Require-Bundle中:
          • visibility – If the value is private (Default), then all visible packages from the required bundles are not re-exported. If the value is reexport then bundles that require this bundle will transitively have access to these required bundle’s exported packages. That is, if bundle A requires bundle B, and bundle B requires bundle C with visibility:=reexport then bundle A will have access to all bundle C’s exported packages as if bundle A had required bundle C.
          • visibility – 如果值是private(默認值),那么所有required bundles中可見的包都不會重新輸出。如果值是reexport ,那么需要這個bundle的bundles將可以訪問這些required bundle輸出的包。也就是說,如果bundle A需要bundle B,bundle B需要bundle C,bundle B的頭Require-Bundle 的visibility ="reexport",那么A將可以訪問C輸出的包,就像A需要C一樣。

          • resolution – If the value is mandatory (default) then the required bundle must exist for this bundle to resolve. If the value is optional, the bundle will resolve even if the required bundle does not exist.
          • resolution – 如果值是mandatory (默認值),那么required bundle必須存在用于解析這個bundle。如果值是optional,那么這個bundle將會被解析,即使required bundle不存在。

          The following matching attribute is architected by the Framework:
          以下匹配屬性由框架構造:
          • bundle-version – The value of this attribute is a version range to select the bundle version of the required bundle. See Version Ranges on page 28. The default value is [0.0.0,∞).
          • bundle-version – 這個屬性的值是一個版本范圍,用于選擇required bundle的版本。默認值是[0.0.0,∞)。

          A given package may be available from more than one of the required bundles. Such packages are named split packages because they derive their contents from different bundles. If these different bundles provide the same classes unpredictable shadowing of classes can arise, see Issues With Requiring Bundles on page 66. However, split packages without shadowing are explicitly permitted.

          For example, take the following setup:
          A: Require-Bundle: B
          Export-Package: p
          B: Export-Package: p;partial=true;mandatory:=partial

          If bundle C imports package p, it will be wired to package A.p, however the contents will come from B.p > A.p. The mandatory attribute on bundle B’s export definition ensures that bundle B is not accidentally selected as exporter for package p. Split packages have a number drawbacks that are discussed in Issues With Requiring Bundles on page 66.
          如果bundle C引入包p,它將被連接到包A.p,可是這個包是從B.p到A.p。bundle B的輸出定義的強制屬性確保了bundle B不會被意外的選擇為包p的輸出者。

          Resources and classes from a split package must be searched in the order in which the required bundles are specified in the Require-Bundle header.

          As an example, assume that a bundle consists of a number of bundles and a number of language resources (also bundles) that are optional.
          Require-Bundle: com.acme.facade;visibility:=reexport,
          com.acme.bar.one;visibility:=reexport,
          com.acme.bar.two;visibility:=reexport,
          com.acme.bar._nl;visibility:=reexport;resolution:=optional,
          com.acme.bar._en;visibility:=reexport;resolution:=optional

          A bundle may both import packages (via Import-Package) and require one or more bundles (via Require-Bundle), but if a package is imported via Import-Package, it is not also visible via Require-Bundle: Import-Package takes priority over Require-Bundle, and packages which are exported by a required bundle and imported via Import-Package must not be treated as split packages.

          In order to be allowed to require a named bundle, the requiring bundle must have BundlePermission[<bundle symbolic name>, REQUIRE], where the bundle symbolic name is the name of the bundle that is required. The required bundle must be able to provide the bundle and must therefore have BundlePermission[<bundle symbolic name>, PROVIDE], where the name designates the requiring bundle. In the case a Fragment bundle requires another bundle, the Bundle Permission must be checked against the Fragment bundle’s Protection Domain.
          一個bundle可以同時引入包(通過Import-Package)和require一個或多個bundles(通過Require-Bundle), 但是如果一個包通過Import-Package被引入,那么通過Require-Bundle引入的相同的包不會可見,因為Import- Package的優先級大于Require-Bundle,被required bundle輸出并通過Import-Package引入的包不能當作split包來對待。
          為了被允許需求一個命名bundle,requiring bundle必須有BundlePermission[<bundle symbolic name>, REQUIRE](bundle權限),這里的bundle symbolic name是被需要的bundle的名字。這個被需要的bundle必須能提供自己出去,因此它必須有 BundlePermission[<bundle symbolic name>, PROVIDE],這里的bundle symbolic name指向那個requiring bundle。在片段bundle需求其他bundle的情況下,bundle權限必須與片段bundle的域保護進行核查(這里應該是指宿主 bundle的權限)。

          3.13.2 Split Package Compatibility

          A package is a split package whenever there are multiple sources for the package; only bundles using the Require-Bundle header can have split packages.

          A source is a bundle that provides the given package. Both the required bundles as well as the requiring bundle can act as a source. The required bundles and the requiring bundle can only contribute their exported packages.

          Exported split packages from two bundles are compatible if the package sources for one are a subset of the other.

          對于一個包來說,只要有多個源,那它就是一個分隔包;只有使用頭Require-Bundle的bundle才有分隔包。
          一個源是提供了這個包的bundle。required bundles和requiring bundle都可以成為一個源,它們只能分發它們自己的輸出包。
          從兩個bundle輸出的分隔包是兼容的,如果這個包的其中一個源是另一個源的子集。

          3.13.3 Issues With Requiring Bundles

          The preferred way of wiring bundles is to use the Import-Package and Export-Package headers because they couple the importer and exporter to a much lesser extent. Bundles can be refactored to have a different package composition without causing other bundles to fail.

          The Require-Bundle header provides a way for a bundle to bind to all the exports of another bundle, regardless of what those exports are. Though this can seem convenient at first, it has a number of drawbacks:

          連接bundles的首選方式是使用頭Import-Package和Export-Package,因為它們將輸出者和引入者連接到一個很小的范圍,bundles可以被重構來含有一個不同的組成包,而不需要使其他bundles失敗。
          頭Require-Bundle提供的方式是綁定那個bundle所有的輸出包,而不管這些輸出包是什么。盡管這看起來很方便,但是有以下缺點:

          • Split Packages – Classes from the same package can come from different bundles with Require bundle, such a package is called a split package. Split packages have the following drawbacks:
          • Split Packages – 同一個包中的類,可以來自不同的bundles,這個包成為分隔包。分隔包有以下缺點:
            • Completeness – Split packages are open ended, there is no way to guarantee that all the intended pieces of a split package have actually been included.
            • Completeness – 分隔包是入口處,沒有辦法保證所有這個分隔包所需的部分都已經被包含了。
            • Ordering – If the same classes are present in more than one required bundle, then the ordering of Require-Bundle is significant. A wrong ordering can cause hard to trace errors, similar to the traditional class path model of Java.
            • Ordering – 如果相同的類出現在多個required bundle中,那么Require-Bundle的順序就變得很重要了,一個錯誤的順序會讓錯誤跟蹤變得很難,這與JAVA傳統的類路徑模式相似。
            • Performance – A class must be searched in all providers when packages are split. This increases the number of times that a ClassNotFoundException must be thrown which can introduce a significant overhead.
            • Performance –在分隔包中,一個類必須被查找于所有的提供者,這會增加ClassNotFoundException必須被拋出的次數,這是很大的性能支出。
            • Confusing – It is easy to find a setup where there is lots of potential for confusion. For example, the following setup is non-intuitive.
          A: Export-Package: p;uses:=q Import-Package: q
          B: Export-Package: q
          C: Export-Package: q
          D: Require-Bundle: B, C Import-Package: p



          In this example, bundle D merges the split package q from bundles B and bundle C, however, importing package p from bundle A puts a uses constraint on package p for package q. This implies that bundle D can see the valid package q from bundle B but also the invalid package q from bundle C. This wiring is allowed because in almost all cases there will be no problem. However, the consistency can be violated in the rare case when package C.q contains classes that are also in package B.q.
          在這個例子中,bundle D合并了bundle B和C的包q,可是A.p,為包q設置了uses指令,約束到包A.p上。這暗示了bundle D可以看見可用的B.q,也可以看見不可用的C.q(頭Require-Bundle中,B在C前面)。這個連接是被允許的,在大多數案例中不會有問題。但是,當C.q和B.q中包含同相同的類時,就會發生問題。
          • Mutable Exports – The feature of visibility:=reexport that the export signature of the requiring bundle can unexpectedly change depending on the export signature of the required bundle.
          • Mutable Exports – visibility:=reexport的特性,requiring bundle的輸出信號可以根據required bundle的輸出信號而發生不可預期的改變。
          • Shadowing – The classes in the requiring bundle that are shadowed by those in a required bundle depend on the export signature of the required bundle and the classes the required bundle contains. (By contrast, Import-Package, except with resolution:=optional, shadows whole packages regardless of the exporter.)
          • Shadowing – the requiring bundle中的類會被那些required bundle遮擋,根據required bundle的輸出信號和包含的類(相比之下,Import-Package,除了resolution:=optional,會遮擋所有的包而不管輸出 者)。(深層優先的類路徑查找順序)
          • Unexpected Signature Changes – The Require-Bundle directive visibility:=private (the default) may be unexpectedly overridden in some circumstances as the following example shows.
          • Unexpected Signature Changes – 在某些情況下,Require-Bundle的指令visibility:=private可能會出乎預料的被重載
          A: p (private, not exposed in manifest)
          Require-Bundle: B;visibility:=reexport,
          C;visibility:=private
          B: Export-Package: p
          C: Export-Package: p

          The export signature of bundle A will consist of only package p. However, package p is split. The Framework searches for a class in package p in bundle B, then bundle C, and last bundle A.
          So the visibility:=private directive on Require-Bundle C had no effect relative to package p. However, if bundle B was changed to stop exporting package p, then the directive would take effect and package p would drop out of bundle A's export signature. This is depicted in Figure 3.22.
          bundle A的輸出信號僅由包p組成,可是包p是個分隔包。框架會先在bundle B中的包p中查找一個類,然后再在bundle C中查找,最后才查找bundle A。所以Require-Bundle C上的指令visibility:=private不會影響到包p。但是,如果bundle B停止輸出包p,那么這個指令將會受到影響,包p也將退出bundle A的輸出信號。



          3.14 Fragment Bundles

          Fragments are bundles that are attached to a host bundle by the Framework. Attaching is done as part of resolving: the Framework appends the relevant definitions of the fragment bundles to the host’s definitions before the host is resolved. Fragments are therefore treated as part of the host, including any permitted headers; they must not have their own class loader. Fragments must have their own Protection Domain.

          A key use case for fragments is providing translation files for different locales. This allows the translation files to be treated and shipped independently from the main application bundle.

          When an attached fragment bundle is updated, the content of the previous fragment must remain attached to its host bundle. The new content of the updated fragment must not be allowed to attach to the host bundle until the Framework is restarted or the host bundle is refreshed. During this time, an attached fragment will have two versions: the old version, attached to the
          old version of the host, and a new fragment bundle that can get attached to a new version or to a different host bundle.

          片段是由框架附加在一個主bundle上的bundles。附加過程是解析過程的一部分:框架在主bundle被解析之前將片段bundles的相關定義 附加到主bundle的定義上。因此,片段可看作主bundle的一部分,包括所有允許的頭。片段必須不能有它們自己的class loader。片段必須有它們自己的保護域。

          片段的一個重要案例是為不同的locales提供翻譯文件。這允許翻譯文件可獨立于主應用bundle被處理和裝載。

          當一個片段被更新時,上一個片段的內容必須被保留在它的宿主bundle上。更新片段的內容必須不能被附加到那個宿主bundle,知道框架重啟或那個宿 主bundle被刷新。期間,這個片段會有2個版本:老版本,附加在老版本的宿主bundle,新的片段能附加在一個新版本的bundle或是其他宿主 bundle上。

          In this case, the Package Admin service must return information only for the last version of the supplied bundles. In the previous described case, the getHosts method must return the host bundle of the new version of the fragment bundle, and the getFragments method must return the fragment bundles attached to the new version of the host bundle.

          在這里,Package Admin service必須只能為那個提供的bundle最后面的那個版本返回信息。在前面的例子中,getHosts方法必須返回新版本片段bundle的宿主 bundle,getFragments方法必須返回附加在新的主bundle上的片段bundle。

          When attaching a fragment bundle to a host bundle the Framework must perform the following steps:
          當附加一個片段bundle到一個主bundle時,框架必須執行以下步驟:

          1 Append the import definitions for the Fragment bundle that do not conflict with an import definition of the host to the import definitions of the host bundle. A Fragment can provide an import statement for a private package of the host. The private package in the host is hidden in that case.
          2 Append the Require-Bundle entries of the fragment bundle that do not conflict with a Require-Bundle entry of the host to the Require-Bundle entries of the host bundle.
          3 Append the export definitions of a Fragment bundle to the export definitions of the host bundle unless the exact definition (directives and attributes must match) is already present in the host. Fragment bundles can therefore add additional exports for the same package name. The bundle-version attributes and bundle-symbolic-name attributes will reflect the host bundle.

          1. 將片段bundle中不影響主bundle引入定義的引入定義添加到主bundle的引入定義中。一個片段可以為主bundle中一個私有包提供引入聲明,主bundle中的那個私有包是隱藏的。
          2. 將片段bundle中不影響主bundle的Require-Bundle實體的Require-Bundle實體添加到zhu主bundle的Require-Bundle實體中。
          3. 將片段bundle中不影響主bundle輸出定義的輸出定義添加到主bundle的輸出定義中,除非主bundle中已經有了這樣一個定義(指令和屬性 必須匹配)。因此,片段bundles可以有對同一個包名的輸出。屬性bundle-version和屬性bundle-symbolic-name將會 反射到主bundle。

          A host and a fragment conflict when they cannot resolve to provide a consistent class space. If a conflict is found, the Fragment bundle is not attached to the host bundle.

          A Fragment bundle must enter the resolved state only if it has been successfully attached to its host bundle. During runtime, the fragment’s JAR is searched after the host’s bundle class path as described in Fragments During Runtime on page 70.

          A Fragment bundle can not be required by another bundle with the Require-Bundle header.

          當一個主bundle和一個片段bundle不能解析來提供一個一致的的類空間時,它們會發生沖突,片段bundle將不再添加到這個主bundle。
          一個片段bundle僅當它成功附加到一個主bundle后,它才進入resolved狀態,它的JAR包將在主bundle的類路徑之后被查找。
          其他bundle不能使用頭Require-Bundle來require一個片段bundle。

          3.14.1 Fragment-Host

          A fragment is a bundle that is attached to one other bundle called its host bundle. The components of the fragment, like the Bundle-Classpath and other definitions, are added at the end of the related definitions of the host bundle. In the case of the Export-Package header, bundle dependent attributes like bundle-version and bundle-symbolic-name come from the host. All classes and resources within the fragment bundle must be loaded using the class loader of the host bundle.
          一個片段是一個bundle,被它附加的另一個bundle叫做它的宿主bundle。片段bundle的組件,就像Bundle-Classpath或 其他定義,被添加在主bundle的相關定義的末尾。在頭Export-Package中,bundle依賴的屬性,例如bundle-version和 bundle-symbolic-name均來自主bundle。片段bundle中所有的類和資源必須使用主bundle的class loader加載。

          The Fragment-Host manifest header must conform to the following syntax:
          Fragment-Host ::= bundle-description
          bundle-description ::= symbolic-name
          (';' parameter ) * // See 1.3.2

          The following directives are architected by the Framework for Fragment-Host:
          框架為Fragment-Host構造了以下指令:
          • extension – Indicates this extension is a system or boot class path extension. It is only applicable when the Fragment-Host is the System Bundle. This is discussed in Extension Bundles on page 72. The following values are supported:
          • extension – 指這個擴展是系統或boot 類路徑擴展,它只能在Fragment-Host(宿主bundle)是系統bundle的情況下才可用。支持以下值:
            • framework - The fragment bundle is a Framework extension bundle.
            • framework - 片段bundle是框架的擴展bundle。
            • bootclasspath - The fragment bundle is a boot class path extension bundle.
            • bootclasspath - 片段bundle是boot類路徑擴展bundle。

          The fragment must be the bundle symbolic name of the implementation specific system bundle or the alias system.bundle. The Framework should fail to install an extension bundle when the bundle symbolic name is not referring to the system bundle.
          片段必須是實現特殊系統bundle的bundle標記名或別名system.bundle(應該是指片段bundle的標記名)。當片段的標記名沒有引用到系統bundle時,框架必須使這個擴展安裝失敗。

          The following attributes are architected by the Framework for Fragment-Host:

          • bundle-version – The version range to select the bundle that provides the host bundle. See Version Matching on page 41. The default value is [0.0.0,∞).
          • bundle-version – 版本范圍,用于選擇提供宿主的bundle

          When a fragment bundle becomes resolved, the Framework must attach the
          fragment bundle to the selected host bundle with the highest version.

          When a fragment bundle is attached to its host bundle, it logically becomes part of it. All classes and resources within the fragment bundle must be loaded using the class loader of its host bundle. The fragment bundles of a host bundle must be attached to the host bundle in the order that the fragment bundles are installed, which is in ascending bundle ID order. If an error occurs during the attachment of a fragment bundle then the fragment bundle must not be attached to the host. A fragment bundle must enter the resolved state only if it has been successfully attached to its host bundles.

          In order for a host bundle to allow fragments to attach, the host bundle must have BundlePermission[<bundle symbolic name>,HOST]. In order to be allowed to attach to a host bundle, a fragment bundle must have BundlePermission[<bundle symbolic name>,FRAGMENT].

          當一個片段bundle解析之后,框架必須將這個片段bundle附加到被選擇的版本最高的主bundle上。
          當一個片段bundle被附加到它的主bundle后,理論上它就成了主bundle的一部分。片段bundle中所有的類和資源必須使用它的宿主 bundle的class loader去加載。一個主bundle的片段bundles必須按照它們被安裝的順序附加到主bundle上,也就是根據他們的bundle ID的升序。如果在附加過程中發生錯誤,那么片段bundle不能附加到主bundle上。一個片段bundle只有在成功附加到它的所有主 bundles后才能進入resolved狀態。
          為了使一個主bundle允許被附加片段,這個主bundle必須有BundlePermission[<bundle symbolic name>,HOST],為了使一個片段被允許附加到一個主bundle,這個片段bundle必須有a fragment bundle must have BundlePermission[<bundle symbolic name>,FRAGMENT]

          3.14.2 Fragments During Runtime

          All class or resource loading of a fragment is handled through the host’s class loader, a fragment must never have its own class loader. Fragment bundles are treated as if they are an intrinsic part of their host.

          Though a fragment bundle does not have its own class loader, it still must have a separate Protection Domain when it is not an extension fragment. Each fragment can have its own permissions linked to the fragment bundle’s location and signer.

          A host bundle’s class path is searched before a fragment’s class path. This implies that packages can be split over the host and any of its fragments. Searching the fragments must be done in ascending bundle ID order. This is the order that the fragment bundles were installed.

          片段所有類和資源的加載都由它的主bundle的class loader來處理,它不能擁有自己的class loader。片段bundles被看成是它們的宿主bundle的一部分。
          盡管一個片段bundle沒有它自己的class loader,如果它不是一個擴展片段,它還是必須有一個保護域。每個片段都有它自己的連接到片段bundle的路徑和簽名者的權限。
          一個主bundle的類路徑在片段bundle的類路徑之前被查找,這暗示了包可以被分割到主bundle和片段bundles。片段的查找必須根據它們被安裝后的ID的升序進行。


          Figure 3.23 shows a setup with two fragments. Bundle B is installed before bundle C and both bundle B and bundle C attach to bundle A. The following table shows where different packages originate in this setup. Note that the order of the append (>) is significant.
          圖3.23顯示了兩個片段的設置。bundle B在C之前被安裝,它們都被附加到bundle A。下面的表格顯示了這個安裝的兩個包的本質區別,注意>的順序是很重要的。

          Table 3.4 Effect of fragments on searching

           Package Requested  From  Remark
           p  A.p > B.p  Bundle A exports package p, therefore, it will search its class path for p. This class path consists of the JAR and then its Fragment bundles.
           q  D.q  The import does not handle split packages and package q is imported from bundle D. Therefore, C.q is not found.
           r  A.r > B.r  Package r is not imported and therefore comes from the class path.
           s  C.s  
           t  B.t > C.t  

          In the example above, if package p had been imported from bundle D, the table would have looked quite different. Package p would have come from bundle D, and bundle A’s own contents as well as the contents of bundle B would have been ignored.
          在上面的例子中,如果包p是從bundle D引入的,那么這個表格將發生很大變化。包p來自bundle D,A.p和B.p將被忽略(D的類路徑先被查找)。

          If package q had bundle D, then the class path would have to be searched, and A.q would have consisted of A.q > C.q.

          Fragments must remain attached as long as the host remains resolved. When a host bundle becomes unresolved, then all attached Fragment bundles must be detached from the host bundle. When a fragment bundle becomes unresolved the Framework must:
          • Detach it from the host
          • Re-resolve the host bundle
          • Reattach the remaining attached fragment bundles.

          A Fragment bundle can become unresolved by calling the refreshPackages method or the resolveBundle method on itself or on its host.

          主bundle處于resolved期間,片段bundle必須一直保持附加狀態。當一個主bundle變成unresolved時,所有的附加片段bundle必須從主bundle分離出來。當一個片段bundle變得unresolved時,框架必須:
          • 將其分離出主bundle
          • 重新解析主bundle
          • 重新附加片段bundles
          一個片段bundle可以通過調用方法refreshPackages或調用主bundle的或它自己的resolveBundle方法變成unresolved。

          3.14.3 Illegal Manifest Header for Fragment Bundles

          The following list contains the headers that must not be used in a fragment bundle:
          一下列表包含了在一個片段bundle中必須不能使用的頭:
          • Bundle-Activator

          3.15 Extension Bundles

          Extension bundles can deliver optional parts of the Framework implementation or provide functionality that must reside on the boot class path. These packages cannot be provided by the normal import/export mechanisms.
          擴展bundles能夠提供框架實現的可選部分或提供必須在boot類路徑中的功能(包)。這些包不能使用平常的引入/輸出機制。

          Boot class path extensions are necessary because certain package implementations assume that they are on the boot class path or are required to be available to all clients. An example of a boot class path extension is an implementation of java.sql such as JSR 169. Boot class path extensions are not required to be implemented by a compliant framework, see Optional on page 64.
          Boot類路徑擴展是有必要的,因為某些實現包假設它們處于boot類路徑上或對所有required的客戶端可用。boot類路徑擴展的一個例子是java.sql的實現,就像JSR 169.boot類路徑擴展的實現不是必須的。

          Framework extensions are necessary to provide implementation aspects of the Framework. For example, a Framework vendor could supply the optional services like Permission Admin service and Start Level service with Framework extension bundles.
          框架擴展對于提供框架的實現部分是由必要的。例如,一個框架提供者可以通過擴展bundles提供一些可選服務,就像Permission Admin service和 Start Level service

          An extension bundle should use the bundle symbolic name of the implementation system bundle, or it can use the alias of the system bundle, which is system.bundle.
          一個擴展bundle應該使用系統實現bundle的標記名,或使用系統bundle的別名system.bundle。

          The following example uses the Fragment-Host manifest header to specify an extension bundle for a specific Framework implementation.
          下面這個例子使用頭Fragment-Host來指定一個框架細節實現的擴展bundle。
          Fragment-Host: com.acme.impl.framework; extension:=framework

          The following example uses the Fragment-Host manifest header to specify a boot class path extension bundle.
          Fragment-Host: system.bundle; extension:=bootclasspath

          The following steps describe the life cycle of an extension bundle:
          下面的步驟描述了一個擴展bundle的生命周期:
          1 When an extension bundle is installed it enters the INSTALLED state.
          2 The extension bundle is allowed to enter the RESOLVED state at the Frameworks discretion, which can require a Framework re-launch.
          3 If the extension bundle is refreshed then the Framework must shutdown, the host VM must terminate, and the Framework must be relaunched.
          4 If a RESOLVED extension bundle is refreshed then the Framework must shutdown; the host VM must terminate and framework must be relaunched.
          5 When a RESOLVED extension bundle is updated or UNINSTALLED, it is not allowed to re-enter the RESOLVED state. If the extension bundle is refreshed then the Framework must shutdown; the host VM must terminate and framework must be re-launched.

          1. 當一個擴展bundle被安裝后,它進入INSTALLED狀態。
          2. 擴展bundle可以進入RESOLVED狀態,這由框架自行決定,但是需要框架重啟。
          3. 如果這個擴展bundle被刷新,那么框架必須shutdown,VM必須終止,框架必須被重啟。
          4. 如果一個resolved狀態的擴展bundle被刷新,那么框架必須shutdown,VM必須終止,框架必須被重啟。
          5. 當一個resolved狀態的擴展bundle被更新或進入uninstalled狀態時,它將不允許重新進入resolved狀態,如果它被刷新,那么框架必須shutdown,VM必須終止,框架必須被重啟。

          It is valid to update an extension bundle to a bundle of another type. If the old extension bundle is resolved then it must be attached as a fragment to the system bundle. When this bundle is updated the old content of the bundle must remain attached to the system bundle until the system bundle is refreshed or the extension bundle is refreshed (using Package Admin service). This must initiate a VM and Framework restart. When the framework comes back up the new content of the bundle may be resolved.

          All Bundle events should be dispatched for extension bundles as for ordinary bundles.

          可以將擴展bundle更新成其他類型的bundle。如果原來的那個擴展bundle處于resolved狀態,那么它必須被作為一個片段附加到系統 bundle。當這個bundle被更新后,它以前的內容必須保持附加在系統bundle知道系統bundle被刷新或這個擴展bundle被刷新。這必 須使一個VM和框架重啟。當框架重啟后,新bundle可以被解析。
          所有的bundle事件必須被分發到擴展bundle,與普通bundle一樣。

          3.15.1 Illegal Manifest Headers for Extension Bundles

          An extension bundle must throw a BundleException if it is installed or updated and it specifies any of the following headers.
          如果一個擴展bundle被安裝或更新并且指定了下列任何一個頭,必須拋出一個BundleException
          • Import-Package
          • Require-Bundle
          • Bundle-NativeCode
          • DynamicImport-Package
          • Bundle-Activator
          Both boot class path and framework extension bundles are permitted to specify an Export-Package header. Any exported packages specified by a framework extension bundle must be exported by the System Bundle when the extension bundle is resolved.
          boot類路徑和框架擴展bundle都可以指定頭Export-Package。當擴展bundle被解析時,所有它指定的輸出包都必須由系統bundle來輸出。

          3.15.2 Class Path Treatment

          A boot class path extension bundle’s JAR file must be appended to the boot class path of the host VM. A framework extension bundle’s JAR is appended to the class path of the Framework.

          Extension bundles must be appended to their class path in the order in which the extension bundles are installed: that is, ascending bundle ID order.

          How a framework configures itself or the boot class path to append the extension bundle’s JAR is implementation specific. In some execution environments, it may be impossible to support extension bundles. In such environments, the Framework must throw a BundleException when such an
          extension bundle is installed. The resulting Bundle Exception must have a cause of type UnsupportedOperationException.

          一個boot類路徑擴展bundle的JAR包文件必須添加到VM的boot類路徑中,一個框架擴展bundle的JAR包文件必須被添加到框架的類路徑中。
          擴展bundle必須根據他們被安裝時ID的升序被添加到它們的類路徑中。
          一個框架配置或boot類路徑如何添加擴展bundle的JAR包文件是一個特殊實現。在一個執行環境中,可能不支持擴展bundle。如果是這樣,擴展 bundle被安裝時,框架必須拋出一個BundleException ,包含 cause of UnsupportedOperationException

          3.16 Security

          3.16.1 Extension Bundles

          In an environment that has Java 2 security enabled the Framework must perform an additional security check before allowing an extension bundle to be installed. In order for an extension bundle to successfully install, the Framework must check that the extension bundle has All Permissions assigned to it. This means that the permissions of an extension bundle must be setup before the extension bundle is installed.
          在JAVA2安全環境中,框架必須在允許擴展bundle被安裝之前執行一個額外的安全檢查。為了成功安裝一個擴展bundle,框架必須檢查擴展bundle的權限。也就是說在擴展bundle被安裝之前,它的權限必須被設置。

          AllPermission must be granted to extension bundles because they will be loaded under the Protection Domain of either the boot class path or the Framework implementation. Both of these Protection Domains have All Permissions granted to them. It must therefore not be allowed for an extension bundle to be installed unless it already has been granted AllPermissions.
          擴展bundle必須被授予所有權限,因為他們將被加載于它們的boot類路徑或框架實現的保護域中。這些保護域都被授予了所有權限。因此除非一個擴展bundle有所有權限,否則不能被安裝。

          The installer of an extension bundle must have AdminPermission[<extension bundle>,EXTENSIONLIFECYCLE] to install an extension bundle.
          擴展bundle的安裝者必須有AdminPermission[<extension bundle>,EXTENSIONLIFECYCLE]權限。

          3.16.2 Bundle Permission

          Most package sharing permissions are based on Package Permission. However, fragments and required bundles use the bundle symbolic name to handle sharing. The Bundle Permission is used to control this type of package sharing.
          大部分包共享權限是基于Package Permission的??墒瞧蝏undle和required bundles是使用bundle標記名來操作共享的。Bundle Permission就是用來控制這種類型的包共享。

          The name parameter of the Bundle Permission is a bundle symbolic name. The symbolic name is used as the identifier for the target bundle. A wild card (’.*’ \u002E,\u002A) is permitted at the end of the name.
          Bundle Permission的參數name是一個bundle的標記名,這個標記名用作目標bundle的標識符,通配符"*"可以跟在名字的結尾。

          For example, if fragment bundle A attaches to its host bundle B then fragment bundle A requires BundlePermission("B", "fragment") so that A is permitted to target host bundle B. The direction of the actions is depicted in Figure 3.24.


          The following actions are architected:
          • provide – Permission to provide packages to the target bundle.
          • require – Permission to require packages from the target bundle.
          • host – Permission to attach to the target fragment bundle.
          • fragment – Permission to attach as a fragment to the target host bundle.

          When a fragment contains a Require-Bundle header, the Framework must check the permission against the domain of the fragment.

          3.16.3 Package Permission

          Bundles can only import and export packages for which they have the required permission. A PackagePermission must be valid across all versions of a package.

          A PackagePermission has two parameters:
          • The package that may be exported or imported. A wildcard may be used. The granularity of the permission is the package, not the class name.
          • The action, either IMPORT or EXPORT. If a bundle has permission to export a package, the Framework must automatically grant it permission to import the package.

          A PackagePermission with * and EXPORT as parameters allows the import and export of any package.

          When a fragment adds imports and exports to the host, the framework must check the protection domain of the fragment and not of the related host.

          3.16.4 Resource Permissions

          A Framework must always give a bundle the RESOURCE, METADATA, and CLASS AdminPermission actions to access the resources contained within:
          • Itself
          • Any attached fragments
          • Any resources from imported packages

          A resource in a bundle may also be accessed by using certain methods on Bundle. The caller of these methods must have AdminPermission[bundle, RESOURCE].

          If the caller does not have the necessary permission, a resource is not accessible and null must be returned. Otherwise, a URL object to the resource must be returned. These URLs are called bundle resource URLs. Once the URL object is returned, no further permission checks are performed when the contents of the resource are accessed. The URL object must use a scheme
          defined by the Framework implementation.

          Bundle resource URLs are normally created by the Framework, however, in certain cases bundles need to manipulate the URL to find related resources. For example, a URL can be constructed to a resource that is in the same directory as a given resource.

          URLs that are not constructed by the Framework must follow slightly different security rules due to the design of the java.net.URL class. Not all constructors of the URL class interact with the URL Stream Handler classes (the implementation specific part). Other constructors call at least the parseURL method in the URL Stream Handler where the security check can take place.

          This design makes it impossible for the Framework check the permissions during construction of a bundle resource URL.

          The following constructors use the parseURL method and are therefore checked when a bundle resource URL is constructed.
          URL(String spec)
          URL(URL context, String spec)
          URL(URL context, String spec, URLStreamHandler handler)

          When one of these constructors is called for a bundle resource URL, the implementation of the Framework must check the caller for the necessary permissions in the parseURL method. If the caller does not have the necessary permissions then the parseURL method must throw a Security Exception. This will cause a Malformed URL Exception to be thrown by the URL constructor. If the caller has the necessary permissions, then the URL object is setup to access the bundle resource without further checks.

          The following java.net.URL constructors do not call the parseURL method in the URL Stream Handler, making it impossible for the Framework to verify the permission during construction.

          URL(String protocol, String host, int port, String file)
          URL(String protocol, String host, int port, String file,
          URLStreamHandler handler)
          URL(String protocol, String host, String file)

          Bundle resource URLs that are created with these constructors cannot perform the permission check during creation and must therefore delay the permission check. When the content of the URL is accessed, the Framework must throw a Security Exception if the caller does not have
          AdminPermission[bundle, RESOURCE] for the bundle referenced by the URL.

          3.16.5 Permission Checks

          Since multiple bundles can export permission classes with the same class name, the Framework must make sure that permission checks are performed using the correct class. For example, a bundle that calls the check-Permission method provides an instance of the Permission class:
          void foo(String name) {
            checkPermission(
          new FooPermission(name,"foo"));
          }

          This class of this Permission instance comes from a particular source. Permissions can only be tested against instances that come from the same source.

          Therefore, the Framework needs to look up permissions based on class rather than class name. When it needs to instantiate a permission it must use the class of the permission being checked to do the instantiation. This is a complication for Framework implementers; bundle programmers are not affected.
          Consider the following example:
          Bundle A
          Import-Package: p
          Export-Package: q
          Bundle B
          Import-Package: p
          • Bundle A uses a p.FooService. Usage of this class checks q.FooPermission whenever one of its methods is invoked.
          • Bundle B has a FooPermission in its Protection Domain in a (Conditional) Permission Info object.
          • Bundle B invokes a method in the FooService that was given by bundle A.
          • The FooService calls the checkPermission method with a new FooPermission instance.
          • The Framework must use a FooPermission object that is from the same class loader as the given FooPermission object before it can call the implies method. In this case, the FooPermission class comes from package A.q.

          After the permission check, bundle B will have a FooPermission instantiated using a class from a package it does not import. It is therefore possible that the Framework has to instantiate multiple variations of the FooPermission class to satisfy the needs of different bundles.

          posted on 2008-05-09 17:56 gembin 閱讀(1273) 評論(0)  編輯  收藏 所屬分類: OSGi

          導航

          統計

          常用鏈接

          留言簿(6)

          隨筆分類(440)

          隨筆檔案(378)

          文章檔案(6)

          新聞檔案(1)

          相冊

          收藏夾(9)

          Adobe

          Android

          AS3

          Blog-Links

          Build

          Design Pattern

          Eclipse

          Favorite Links

          Flickr

          Game Dev

          HBase

          Identity Management

          IT resources

          JEE

          Language

          OpenID

          OSGi

          SOA

          Version Control

          最新隨筆

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          free counters
          主站蜘蛛池模板: 冀州市| 增城市| 铁岭县| 毕节市| 台东县| 金寨县| 青田县| 吉木萨尔县| 伊宁县| 鞍山市| 尤溪县| 万盛区| 阿图什市| 浦城县| 瑞昌市| 冷水江市| 天水市| 太谷县| 东光县| 扶余县| 巴林右旗| 甘南县| 杂多县| 敦煌市| 洛南县| 吉木乃县| 万宁市| 南乐县| 东城区| 营山县| 信丰县| 富宁县| 庐江县| 昂仁县| 龙海市| 西安市| 宣恩县| 丰宁| 东丽区| 石狮市| 莱阳市|