ぱと隊長日誌

ブログ運用もエンジニアとしての生き方も模索中

JJUG ナイト・セミナー「Neil Bartlett氏によるOSGi講座」レポート

はじめに

JJUG ナイト・セミナー「Neil Bartlett氏によるOSGi講座」に参加してきました。
JJUG ナイト・セミナー 「Neil Bartlett氏によるOSGi講座」 5/27(月)開催 | 日本Javaユーザーグループ
そのレポートを公開します。

今回のセミナーは録画が公開されています。最後のリンク集に掲載しましたので、ぜひご覧ください。

なお、[参考]としている個所は私が挿入しています(補足や参考資料など)。発表者の意図したものではありませんので、その旨ご了承ください。

Neil Bartlett氏によるOSGi講座

Introduction

OSGiの基本とそれが抱える課題についてお話しする。
OSGiとはJavaで唯一のモジュールシステム。
OSGiを使うユーザは世界的に見てもあまり多くはなく、少しずつ増えていっている状態。
OSGiがなかなか広まらない理由として
・レガシーのアプリケーション
・難しい
・(少なくとも昔は)ツールが十分ではない

レガシーアプリケーションのモジュラー化には取り組んでいる。これはいつも課題になっており、取り組まなければいけない。
でも、後の二つは誤解だ。これから説明していく。

Rod JohnsonはOSGiでの開発は簡単にできない(cannot)といっている。でも"cannot"と言い切るのは間違いだ!

Services

OSGiを使って実現できること。
疎結合
  サービスのプロバイダとコンシューマがお互いに依存しなくて済む。
・高度に動的である
  例えば、サービスを提供できなくなったら外すことができる。
  逆にサービスを使えるようになればそれを組み込むことができる。
これらの特性はプログラミングを難しくしている。OSGiには低レベルのAPIがあるので、それらを使ってプログラミングすることはできるが、難しい。

サービスを低レベルのAPIを使って実装することは難しい。ではどうするかというと、高レベルのフレームワークを使えばよい。
フレームワークを使うと
Javaアノテーションが使える
・サービスのライフサイクル管理ができる
・サービスの状態を動的に可視化できる

BndtoolsとはOSGiの一つだ。
[参考]
Bndtoolsのサイトです。
Bndtools

サービスの状態を見てみよう。
X-Rayという機能を使うことでサービスのライフサイクルが見える
X-Ray左側に並んでいる黄色の箱がバンドル。その右の△がサービス。白い△はpublishなんだけど、まだだれも使っていないもの。
[参考]
X-Rayのキャプチャの下あたりに画面の説明があります。
Software Simplexity: X-Rays for OSGi

コードを書くとEclipseがビルドしてくれる。それに加えてBndtoolsがサービス実行時にJVMへロードする。なのでJVMを再起動する必要がない。

Dependencies

2つ目のテーマとして依存関係の管理を見ていく。

モジュールのidentityを名前に依存してしまうと、密結合になってしまう。
提供しているモジュール自体に依存してしまうと、他のモジュールを使えなくなってしまう。例えば、loggingというサービスに依存する必要はあるが、具体的なLog4jとかSLF4Jには依存させたくない。
特定のモジュールの名前に依存するのではなく、モジュールの機能に依存する。その具体的な例としてはパッケージ。

Javaのパッケージに依存しようとすると、問題がある。これまでの歴史の中でJavaのパッケージは膨れ上がってしまった。Javaのパッケージは大量にあるため、手でメンテナンスすることは困難だ。それがOSGiが難しいといわれる理由の一つになっている。

でもimport文にヒントがある。ここには依存するパッケージが挙げられている。この情報はコンパイル後のバイナリにも含まれている。であればこれを使えばいい!
Bndtoolsのすごさはほんの1行宣言しておくことで、クラスファイルがどのパッケージに依存しているかを解析してくれる。
[参考]
http://www.osgi.org/wiki/uploads/CommunityEvent2010/bndtools.pdf
このPDFに『Descriptor-Based』というページがありますが、このようにExport-Package1行書くだけで自動的に展開してくれる、ということを説明していたようです。

Versions

バージョンとは非常に強力なツールだが、バージョン(のルールを)一貫して整合性を保ちながら使っているわけではない。
例えば、1.2, 1.4.6, 3.0, XP, Vista(?)
これらには何かしらルールを与えてはいるが、プログラムにはわからない。

バージョンに何かしら意味を持たせられないなら使う意味はない。バージョンとはある種のコミュニケーションの形式なのだ。それは開発者同士のコミュニケーションのこともあれば、過去の自分とのコミュニケーションのこともある。

OSGiではバージョンの意味を以下のように定義している。
1.0.0 => 1.0.1 バグ修正
1.0.0 => 1.1.0 機能追加(後方互換性を保つ)
1.0.0 => 2.0.0 breaking change(後方互換性を壊す)

使う側はどの幅でライブラリをインポートすべきか?
提供する側はバージョンをどう付与すべきか?
考えないといけない。

バージョンをどう付与するべきかを人間が判断するのは難しい。なのでツールにやってもらう。
Bndtoolsは
・どのバージョン幅でimportすれば良いか自動的に計算してくれる
・exportするときは自動的にバージョンをincrementしてくれる

importの場合
どういうレンジでバージョンをimportしたら良いかは使い方によって異なる。
もしライブラリを自分が使っているだけなら幅広くする。[1.0, 2.0)のように。
I/Fを提供する場合は狭くする必要がある。[1.0, 1.1)のように。

[参考]
ここで指摘されているのは、クライアントなのか実装なのか、ということだと思われます。
OSGiアプリケーションを開発、利用するためのベスト・プラクティス
この記事の図4が端的に表しています。
クライアントであればminorバージョンの変更による影響はありません。ですが、実装はminorバージョンの変更による影響をうけます。

バージョンをincrementする場合
今が1.0.0とすると、
メソッドを消したり名前を変えたとき=>2.0(BreakingChange)
メソッドを追加しただけ=>1.1
という判断を行う。

Bndtoolsがバージョニングのルールを理解し、判断してくれる。

(動作に必要なバンドルのリストを見せ)直接利用するバンドルは少なく、他は単なるバンドルの依存だ。なので、ツールで解決する。
Bndtoolsで直接利用するバンドルさえ選択すれば、その依存関係を解決してくれる。
オプショナリリソースは必須ではないが、必要であれば選択できる。

バージョン表記は
(major).(minor).(micro).(qualifier)
となる。
qualifierは英数字を使える。
バージョン指定はmicro以降を省略しても良い。

質疑応答

Q.
バージョニングの標準化団体はある?
A.
OSGiは標準化団体の一つだ。そこでバージョン体系を定義している。
ただ、他にもバージョンを定義している団体がある。OSGiは他とも協力している。
[参考]
少し話題はそれますが、バージョニングの議論について記事があったので紹介します。
JSR 277論争、バージョニングで再燃

Q.
Jigsawとの違いは?
A.
このスライドを見てくれ!


JigsawはJREのモジュール化を目指したものだ。

Q.
BndtoolsにはMavenのようにリポジトリから取得する仕組みがあるのか?
A.
リポジトリのプラグインがあり、MavenやGitHubとやりとりができる。

Q.
ライブラリに依存するライブラリが異なるバージョンを参照しているような場合、どうなる?
A.
問題ない。モジュールごとにクラスローダが異なるので、それぞれに読み込むことができる。
[参考]
若干メモが怪しいのですが、制約もあるとの事でした。モジュールごとにクラスローダーが異なるので、依存モジュールが同じであっても別のクラスとしてロードされており、モジュールをまたがって依存モジュールを操作しようとするとおかしくなる、ということを説明されていたように思います。
⇒@さんが解説してくださいました。
自作クラスローダーによるキャストの制限 - 水まんじゅう

Q.
OSGiを使って設計する時の注意点は?例えば、モジュールの粒度など。
A.
粒度は常に問題になるが早い段階で考える必要はない。後からリファクタリングできるから。ポイントは低結合、高凝集にすること。
[参考]
以下の記事が参考になります。
メモしきれていませんでしたが、同様のことを説明されていたように思います。
OSGiアプリケーションを開発、利用するためのベスト・プラクティス
『7. 適切なバンドルは適切なクラスと似ており、結合度が低く、凝集度が高い』
『8. 分割されたパッケージや Require-Bundle を避ける』

Q.
JSR277とOSGiがあったのにJSR277がなくなったのはなぜ?
A.
JSR277はJigsawへとなった。
OSGiはアプリケーションのモジュラリティにフォーカスしている。
[参考]
JSR277, JSR294, Jigsaw, OSGiなどの歴史がまとめられています。
OSGi Alliance Blog: Project Jigsaw

Q.
今回日本にきた理由は?
A.
OSGiフォーラムに参加するために来日した。

Q.
mavenとの使い分けは?
A.
mavenはビルド時の依存関係解決のため。OSGiはランタイムの依存関係解決のため。
この二つの依存関係は異なるもので競合するものではない。

Q.
SOAOSGiの関連性は?
A.
SOAはパターンだ。そして、OSGiSOAの一種だ。OSGiはサービスがインスタンスと思えばいい。

リンク集

当日の録画(途中で音声が切れます)


Video streaming by Ustream

@さんによるtweetまとめ
JJUG ナイト・セミナー 「Neil Bartlett氏によるOSGi講座」 - Togetter

Bndtoolsのチュートリアル
Bndtools

InfoQのOSGiに関するコンテンツ
OSGi に関するすべてのコンテンツ
この中でも以下の記事がOSGiを理解するためにお勧めです。
Modular Java:それは何なのか?
Modular Java:静的なモジュール化
Modular Java:動的なモジュール化
Java 7モジュール・システムの懸念点

更新情報

2013/06/05:
・参考リンクを追加しました