はじめに
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.
このスライドを見てくれ!
Q.
BndtoolsにはMavenのようにリポジトリから取得する仕組みがあるのか?
A.
リポジトリのプラグインがあり、MavenやGitHubとやりとりができる。
Q.
ライブラリに依存するライブラリが異なるバージョンを参照しているような場合、どうなる?
A.
問題ない。モジュールごとにクラスローダが異なるので、それぞれに読み込むことができる。
[参考]
若干メモが怪しいのですが、制約もあるとの事でした。モジュールごとにクラスローダーが異なるので、依存モジュールが同じであっても別のクラスとしてロードされており、モジュールをまたがって依存モジュールを操作しようとするとおかしくなる、ということを説明されていたように思います。
⇒@megascusさんが解説してくださいました。
自作クラスローダーによるキャストの制限 - 水まんじゅう
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.
SOAとOSGiの関連性は?
A.
SOAはパターンだ。そして、OSGiはSOAの一種だ。OSGiはサービスがインスタンスと思えばいい。
リンク集
@yamadamnさんによるtweetまとめ
JJUG ナイト・セミナー 「Neil Bartlett氏によるOSGi講座」 - Togetter
InfoQのOSGiに関するコンテンツ
OSGi
この中でも以下の記事がOSGiを理解するためにお勧めです。
Modular Java:それは何なのか?
Modular Java:静的なモジュール化
Modular Java:動的なモジュール化
Java 7モジュール・システムの懸念点
更新情報
2013/06/05:
・参考リンクを追加しました
2018/04/07:
ブログのHTTPS化に伴い、当日の録画リンクを削除しました。