2011年8月11日 星期四

OSGI : the manifest.mf header

OSGI bundle 包含了一個MANIFEST.mf檔, 這個檔描述了java classes 跟其他resource的定義,還有一些osgi相關的header內容, 一個簡單的OSGi manifest.mf 檔如下(from wiki)
Bundle-Name: Hello World
Bundle-SymbolicName: org.wikipedia.helloworld
Bundle-Description: A Hello World bundle
Bundle-ManifestVersion: 2
Bundle-Version: 1.0.0
Bundle-Activator: org.wikipedia.Activator
Export-Package: org.wikipedia.helloworld;version="1.0.0"
Import-Package: org.osgi.framework;version="1.3.0"

這邊針對OSGi 相關的MANIFEST.mf檔的header做簡單的說明


Bundle-Name:
Bundle-Name 定義一個human-readable的名稱,一般可定義一個簡單的名稱來辦別bundle, 沒太大的意義, 不影響bundle

Bundle-SymbolicName:
這個header在manifest.mf檔裡是必要的, 這個header會定義一個唯一的identifier給這個bundle,identifier會跟Bundle-Version做組合,格式如下
Bundle-SymbolicName_Bundle-Version

Bundle-Version:
定義bundle的版本號, 下圖表示了OSGI version number 的format(from OSGI in Action)
比如1.2.3.alpha , 1為大版本號,2為中版本,3為小版本, alpha 為1.2.3版的某個階段


Export-Package
透過Export-Package, 可以針對bundle裡的package export 給其他bundle使用, 一個例子如下
Export-Package: org.foo.shape; vendor="Manning", org.foo.other;
vendor="Manning"
這邊定義了一個屬性vendor,為一個arbitrary attribute, 此屬性是沒有任何意義,OSGi 會忽略此屬性(OSGI in action裡面的說明是如此, vendor is an arbitrary attribute because it has no special
meaning to the framework.),這邊要注意Export-package 不會將子package也一起export出去, 如果有com.bat 跟com.bat.abc , com.bat export後是不包含com.bat.abc的。

Bundle-ClassPath
定義bundle的classes path, 比如說Bundle-ClassPath: .,/WEb-INF/lib,embedded.jar
會指定. 根目錄(必須), 以及/WEB-INF/lib 為classes 的路徑和embedded.jar, "." 為bundle JAR file的root, 在這狀況下bundle會先search rool-relative package, 然後再尋找其他的classes如/WEB-INF/lib下, 接著是embedded.jar裡面.下圖的rule很接近,不過要考慮在bundle範圍內

Import-Package
定義了bundle要import 的package list, 下面是一個Export-Package的定義,
Export-Package: org.foo.shape; vendor="Manning", org.foo.other;
vendor="Manning"
所以我們在import package的時候能這樣做,
Import-Package: org.foo.shape; vendor="Manning"
則Manning 這個vendor屬性會被加到import-package裡面。
下圖是import & export package時會用到的Version Syntax,

下圖是一個完整的Bundle 引用
如果一個bundle 不在active狀態下,service是無法被引用的,但是如果只是要使用其classes的話,這個bundle只要處於resolved狀態就行,引用的classes在什麼時候失效?一旦A bundle從 B bundle引用了一個class成功,當B bundle被stop ,這時A bundle的class引用是還有效的,除非A bundle被refresh時才會解除。

DynamicImport-Package
定義需要動態調用的package list, 比如說一個JDBC driver class,需要調用而不是實現它,這時可以利用DynamicImport-Package, 如果我們設定一個屬性如下
DynamicImport-Package: *
這個將會動態導入任何bundle需要的package,而動態導入的search rule如下,
1:Requests for classes in "java." packages, 委託給parent classloader
2:Requests for classes in an imported package,委託給exporting bundle
3:The bundle class path is searched for the class
4:Requests for classes matching a dynamically imported package are delegated to an
exporting bundle if one is found;

(from OSGi Service Platform Release 4 Version 4.2 Core Specification : 3.8.2 Dynamic import package :
Dynamic importing implies inter-bundle constraints. That is, when a bundle A loads a class from a bundle B using dynamic importing, A is then considered to be dependent on B. If B is refreshed or uninstalled, A is refreshed. This behavior is valuable for maintaining consistency when A actually uses and retains references to B’s classes. However, several serialization scenarios have A simply using B’s classes temporarily (e.g., to load some object stream)—there should be no lasting dependency. )


Fragment-Host
一個bundle如果定義為Fragment的話, 代表它是依附在另一個bundle之上, Fragment-Host屬性為要依附的bundle, fragment bundle 必須要有一個宿主,無法獨立存在,而且使用的是宿主的classloader,
如下圖所示


Require-Bundle
使用require-bundle 會將其export 出來的pakcage 全部import進來, 如下圖

Bundle-ManifestVersion
代表OSGI參考的版本, 2 代表的OSGI R4.0+


Reference:

Wiki OSGI
Creating OSGi bundles


沒有留言:

張貼留言