Smile Engineering blog ( スマイルエンジニアリング・ブログ )

ジェイエスピーからTipsや技術特集、プロジェクト物語を発信します

OSGiの最新仕様を追っかけろ【第1回】

2011-11-02 09:23:19 | OSGi
●はじめに
我が社にはOSGiに関わった人がかなりの人数いる。
OSGiフレームワーク上で動くアプリの開発からOSGiフレームワークそのものの開発まで、関わった深さはそれぞれだが18名ほどになる。
社員数73名の会社なので、25%もの社員が関わりを持っていることになる。
そんな我が社ではOSGiの知識ををビジネスに生かすべく、バンドルを公開したり、OSGiセミナーを企画したりして情報発信を行っている。
詳しくは弊社ホームページを見ていただきたい。
今回のブログへの掲載も同じ意図を持っている。

と同時に、自社業務という大義名分のもと大手を振って最新仕様を触る時間が確保できるという、個人的にうれしい都合もある。


さて、タイトルにある通りこの記事ではOSGiの最新仕様について追っかけることとする。
OSGiの最新仕様は今現在のところ、Release 4, Version 4.3である。
仕様書についてはこちら(本家ホームページを)。

仕様書の「1.6 Changes」を確認すると変更点は
・Replaced Package Admin Service with Wiring API, see Bundle Wiring API Specification on page 137.
・Replaced Start Level Service with Start Level API, see Start Level API Specification on page 151.
・Renumbered the services chapters starting at 50
・Added the following chapters
    ・Resolver Hook Service Specification on page 311
    ・Bundle Hook Service Specification on page 323
    ・Service Hook Service Specification on page 329
    ・Weaving Hook Service Specification on page 343
とある。
どうやらPackageAdminとStartLevelは新しいAPIに取って代わられたらしい。
確かにJavadocを見てみると、"Deprecated"つまり非推奨になっている。なんてこったい。
それと、XXX Hook Serviceという奴が4種類追加になっている。それぞれ何かを契機にコールバックされるサービスだろう。
「Service Hook Service Specification」はR4.2の「Service Hooks Specification」とは別物だろうか。

この記事では上記の新機能について、それぞれ2回ないし3回ほどに分けて機能の解説と実装/動作確認を行っていこうと思う。
第1回目の今回は「Bundle Hook Service Specification」を取り上げる。

なぜ、「1.6 Changes」に記述された順番でないかというと、仕様書よりもJavadocを先に確認した為である。
Javadoc的には"org.osgi.framework.hooks.bundle"が最初にくるのだ。
今後も「1.6 Changes」やJavadocの順番に紹介するとは限らない。


●Bundle Hook Serviceってなにさ
まず、仕様ではFindHookサービスとEventHookサービスを定義している。
FindHookサービスはBundleオブジェクトを戻すメソッドをフィルタリングする為のサービス、
EventHookサービスはListenerに通知するイベントをフィルタリングする為のサービスとされている。
両サービスともフレームワークにより使用されるサービスである。

そして、戻り値としてBundleオブジェクトを取得するもの、またはListenerへの通知を受けるものを"Client"、
Hookサービスをサービス登録するものを"Handler"と定義している。


・EventHookサービス
EventHookサービスはBundleListenerへコールバックするBundleEventをフィルタリングする際に使用する。
フレームワークはBundleEvent発生時、BundleListener#bundleChanged(BundleEvent)をコールバックする前に EventHook#event(BundleEvent, Collection)をコールバックする。
EventHook#event(BundleEvent, Collection)は全てのBundleEvent発生時にコールバックされる。
複数のEventHookサービスが登録されている場合はサービスランキング順に全てのEventHookサービスがコールバックされる。

EventHook#event(BundleEvent, Collection)がコールバックされる際、
第1引数のBundleEventには発生したイベント、
第2引数のCollectionはBundleListnerをリスナー登録しているバンドルのBundleContextが格納されている。
第2引数のコレクションはshrinkable collectionと呼ばれ、要素の削除のみが可能で、追加を行うとUnsupportedOperationExceptionをスローするコレクションである。
このコレクションよりBundleContextを削除することにより、コールバックするBundleEventをフィルタリングすることができる。

例えば、
ClientA、ClientBがBundleListnerをリスナー登録しているが、ClientAにはBundleEventを通知したくない場合、
Handlerは第2引数のCollectionよりバンドルAのBundleContextを特定し削除するようEventHook#event(BundleEvent, Collection)を実装する。
その結果、ClientAのBundleListnerはコールバックされないこととなる。

システム管理的な意味を持つバンドルのBundleEventを一般的なバンドルに通知したくないといった場合に利用できそうだ。
誰もが勝手にEventHookサービスを登録してしまってはシステムが破綻するので、ServicePermissionで厳しく制限することになるだろう。

EventHookサービスのサービス登録にはServicePermission[..EventHook,REGISTER]が必要である。
また、バンドルにこの権限を与える必要は全くないがEventHookサービスの取得にはServicePermission[..EventHook,GET]が必要である。


・FindHookサービス
FindHookサービスはBundleをリターンするメソッドの戻り値をフィルタリングする際に使用する。
フレームワークはBundleContext#getBundle(long)、BundleContext#getBundles()がコールされた際に、FindHook#find(BundleContext, Collection)をコールバックする。
呼び出し側が対象バンドルのロケーションを知っている場合にはフィルタリングする必要がないとされ、BundleContext#getBundle(String)は対象とならないようだ。
複数のFindHookサービスが登録されている場合はサービスランキング順に全てのFindHookサービスがコールバックされるのはEventHookサービスと同じ。

FindHook#find(BundleContext, Collection)がコールバックされる際、
第1引数のBundleContextにはメソッドをコールしたバンドルのBundleContext、
第2引数のCollectionは戻り値としてリターンされるBundleが格納されている。
第2引数のコレクションはやっぱりshrinkable collectionであるので、追加を行うとUnsupportedOperationException。
このコレクションよりBundleを削除することにより、メソッドの戻り値をフィルタリングすることができる。

例えば、
ClientA、ClientBがフレームワークにインストールされている状況で、ClientAに対してClientBのBundleを取得させたくない場合、
Handlerは第1引数のBundleContextがClientAのものであった場合に、第2引数のCollectionよりClientBのBundleを特定し削除するようFindHook#find(BundleContext, Collection)を実装する。
その結果、ClientAはClientBのBundleを取得できないこととなる。

やはりこちらもシステム管理的な意味を持つバンドルのBundleを一般的なバンドルに取得されたくないといった場合に利用できそうだ。
そしてこちらも誰もが勝手にFindHookサービスを登録してしまってはシステムが破綻するので、ServicePermissionで厳しく制限することになるだろう。

PermissionについてもEventHookサービスとほぼ同様。
FindHookサービスのサービス登録にはServicePermission[..FindHook,REGISTER]が必要である。
やっぱりバンドルにこの権限を与える必要は全くないがFindHookサービスの取得にはServicePermission[..FindHook,GET]が必要である。


●まとめ
機能面から見て、どちらのサービスも一般的なバンドルが使うものではなく、システム管理を行うようなバンドルがサービス登録することになりそうだ。
きっとそのようなバンドルはAdminPermissionを与えられているので、Bundleのヘッダ情報を取得してフルイにかけるのだろう。
それとも、
・基本料金:¥xxx万円、ただしBundle - BundleEventは含まれません。
・オプション1「Bundle」:1Bunldeにつき¥x万円 - フレームワークから目的のBundleが取得できます。
・オプション2「BundleEvent」:1BundleEventにつき¥x万円 - 目的のBundleEventをフレームワークから受け取れます。
みたいな商売か。


●次回の予定
次回はEventHookサービス、FindHookサービスを実装し、実際に動作確認を行う。
R4.3対応のフレームワークは今のところEquinoxとFelixがあるが、どちらで動作確認するかは検討中である。


株式会社ジェイエスピー
システム部
齊藤 貴生


monipet
  動物病院の犬猫の見守りをサポート
  病院を離れる夜間でも安心

ASSE/CORPA
  センサー、IoT、ビッグデータを活用して新たな価値を創造
  「できたらいいな」を「できる」に

OSGi対応 ECHONET Lite ミドルウェア
  短納期HEMS開発をサポート!

GuruPlug
  カードサイズ スマートサーバ

株式会社ジェイエスピー
  横浜に拠点を置くソフトウェア開発・システム開発・
  製品開発(monipet)、それに農業も手がけるIT企業