Apache Felix に自作のバンドル(OSGi Bundle)を登録する

ServiceMix Kernel に採用されているオープンソース OSGi フレームワークApache Felix に関して、自作のバンドル(OSGi Bundle)を作成・登録してみる。

手順は以下の通り。

  1. Bundle クラス作成
  2. JAR ファイル作成
  3. インストール

作業準備として、Felix のアーカイブファイルをダウンロードサイトからダウンロードし、適当なディレクトリに解凍しておきます。

今回は以下の環境を使用しました。

  • Felix 1.4.0(felix-1.4.0.zip)
  • Java SE 6.0 Update 10
  • Gant 1.4.0

Bundle クラス作成

まず、org.osgi.framework.BundleActivator インターフェースを実装した Bundle クラスを作成します。

BundleActivator インターフェースの start メソッドでは Bundle が開始された時の処理を、stop メソッドでは Bundle が停止された時の処理をそれぞれ実装します。

なお、start や stop メソッドの引数として与えられる BundleContext を活用すると、他の Bundle によって登録されているサービスを取得して使用したり、フレームワークからのイベント通知を受け取ったりする事ができるようです。

今回は、標準出力にログを出力するだけの簡単な実装を行いました。

SampleActivator.java
package sample;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class SampleActivator implements BundleActivator {

    public void start(BundleContext context) {
        System.out.println("start : " + getClass());
    }

    public void stop(BundleContext context) {
        System.out.println("stop : " + getClass());
    }
}

JAR ファイル作成

先ほど作成した Bundle クラスをコンパイルし、JAR ファイル化します。
JAR ファイル化する際、META-INF/MANIFEST.MF ファイルに以下のような設定が追加されるようにします。

  • Bundle-Name: Bundle名
  • Bundle-Description: Bundleの説明
  • Bundle-Vendor: ベンダー名
  • Bundle-Version: バージョン
  • Bundle-Activator: BundleActivator 実装クラス名
  • Import-Package: import するパッケージ("," で区切って複数記述可)

Import-Package への org.osgi.framework の設定は必須になります。(Bundle クラスで org.osgi.framework.BundleActivator インターフェースを実装するため)

今回は Gant を使ってコンパイルと JAR ファイルの作成を実施することにします。

以下の Gant 用ビルドファイルでは、Bundle クラスをコンパイルするために Felix インストールディレクトリ 内の bin/felix.jar をクラスパスをに含むようにし、Ant.jar の実行時に MANIFEST.MF への設定追加を行っています。

build.gant

(注)FELIX_HOME 環境変数に Felix のインストールディレクトリを設定している事が前提

includeTargets << gant.targets.Clean

Ant.property(environment: "env")
felixHome = Ant.antProject.properties."env.FELIX_HOME"

destDir = "dest"
classesDir = "$destDir/classes"
jarFile = "sample.jar"

cleanDirectory << destDir

target("default": "") {
    compile()
}

target(init: "") {
    path(id: "project.classpath") {
        pathelement(path: destDir)

        //felix.jar をクラスパスに追加するための設定
        fileset(dir: felixHome) {
            include(name: "bin/*.jar")
        }
    }
}

target(compile: "") {
    depends(init)

    Ant.mkdir(dir: classesDir)

    Ant.javac(srcdir: "src", destdir: classesDir) {
        classpath(refid: "project.classpath")
    }
}

target(build: "") {
    depends(compile)

    Ant.jar(destfile: "${destDir}/${jarFile}", basedir: classesDir) {
        //MANIFEST.MF への設定追加
        manifest {
            attribute(name: "Bundle-Name", value: "Sample Service")
            attribute(name: "Bundle-Description", value: "")
            attribute(name: "Bundle-Vendor", value: "")
            attribute(name: "Bundle-Version", value: "1.0.0")
            attribute(name: "Bundle-Activator", value: "sample.SampleActivator")
            attribute(name: "Import-Package", value: "org.osgi.framework")
        }
    }
}

Gant を実行して jar ファイルを生成。

>gant build

インストール

Felix のインストールディレクトリ内で java -jar bin/felix.jar を実行し、Felix Shell を立ち上げ、作成した JAR ファイルをインストールします。

start コマンドに作成した JAR ファイルの URL を指定すると、インストール後に自動的に開始されます。(インストールだけを行う場合は install コマンドを使用)

今回使用した Felix Shell のコマンドは以下の通り。

  • start [ID] : 指定 Bundle の開始
  • start [URL] : インストール後に開始
  • stop [ID] : 指定 Bundle の停止
  • install [URL] : Bundle のインストール
  • uninstall [ID] : 指定 Bundle のアンインストール
  • ps : Bundle の一覧参照
  • shutdown : コンソールを終了
Felix Shell を使ったインストールとアンインストール

(注)Felix のインストール先ディレクトリで実行

>java -jar bin/felix.jar
・・・
-> start file:///d:/felix_sample/sample.jar
start : class sample.SampleActivator
-> ps
START LEVEL 1
   ID   State         Level  Name
[   0] [Active     ] [    0] System Bundle (1.4.0)
[   1] [Active     ] [    1] Apache Felix Shell Service (1.0.2)
[   2] [Active     ] [    1] Apache Felix Shell TUI (1.0.2)
[   3] [Active     ] [    1] Apache Felix Bundle Repository (1.2.1)
[   4] [Active     ] [    1] Sample Service (1.0.0)
-> uninstall 4
stop : class sample.SampleActivator

以下でも可。

>java -jar bin/felix.jar
・・・
-> install file:///d:/felix_sample/sample.jar
Bundle ID: 4
-> start 4
start : class sample.SampleActivator
-> stop 4
stop : class sample.SampleActivator
-> uninstall 4

Felix Shell が起動すると、カレントディレクトリに felix-cache ディレクトリが作成され、インストールされた Bundle が配置されるようになります。

Felix 1.2.1 のキャッシュディレクトリ

Felix 1.2.1 では、felix-cache の代わりにユーザーのホームディレクトリ内に .felix/[profile name] ディレクトリが作成される。([profile name] は 1.2.1 の Felix Shell の起動時に入力する profile name の値)