OSGi - My Web Application

Grails2.0に備えてOSGiを学ぼう
@第13回 G*ワークショップ
2010/12/9
日本アイ・ビー・エム(株) 須江 信洋
[email protected]
http://twitter.com/nobusue
※資料の内容は個人としての意見・見解を述べたものであり、
所属する企業・組織が内容を保証するものではありません。
(不要かもしれませんが)自己紹介
須江 信洋(すえ のぶひろ)
1970年生まれの40才
ずっとJavaEE関連の仕事をしています




職場は何回か変わってます。。。
G*との関わり





2
Groovyを組み込んだ製品(WebSphere sMash)を売ってます
JGGUGサポート・メンバー
「Groovy イン・アクション」翻訳メンバーの一味
「Groovy入門(仮称)」依然として執筆中です。。。
今日、私がここに出てきた理由は・・・
OSGiって最近よく聞くけど、いったい何者?
それは美味しいですか?
それは開発者を苦しめる新たなバズワードですか?
僕らに何か関係あるんですか?
関係ないけどガンダムUCは商業ベースの同人作品?





という、もろもろの疑問を解決する
ためだと認識しております
3
OSGiってなんで必要なの?一言で教えて。
 ようがす。
Answer:
Javaはコンポーネント
指向プラットフォーム
として欠陥があるからです
4
コンポーネント指向(モジュール指向)プラットフォーム
の要件

モジュール境界が定義できること




モジュール間の依存性管理が可能であること




外部に公開するインターフェース
モジュールに閉じたリソース
物理的なパッケージングの仕様
依存先モジュールの明示
モジュールのバージョン管理
依存関係の解決
モジュールのライフサイクル管理が可能であること



インストール/アンインストール
開始/停止
ライフサイクルイベントへの対応
Javaの現状

モジュール境界の定義に関する課題



クラスやメソッドの可視性だけでは十分な制御が難しい
 publicではクラスローダー全体に公開されてしまう
 そもそも、Javaのクラスはモジュールの単位としては細かすぎる
JARはモジュールとしては機能不足
 単に複数のクラスやリソースをまとめる機能のみ
 一旦ロードされた後は、個別のクラス単位で認識されるのみ(JARは意識しない)
モジュール間の依存性管理に関する課題




Project Jigsawで
モジュール化機構を導入
ただしJava8(2012年予定)
静的な依存関係はコンパイルしてみないと分からない
実行時の依存関係は実行してみないと分からない
バージョン管理機能がない
モジュールのライフサイクル管理に関する課題


一旦ロードしたクラスはアンロードできない
ライフサイクルという概念はない(ロードされたら直ちに有効となる)
OSGi小史




1999年:「Open Service Gateway Initiative」が設立
 当初は家庭や小規模オフィス向けの
ゲートウェイ装置で動作するサービスプログラムの実行基盤
2003年:名称を「OSGi Alliance」に変更
 対象を車載機器やモバイル端末、エンタープライズシステムに拡大
2003年:Eclipse 3.0がプラグイン管理システムとしてOSGi仕様を採用
 Javaの世界での知名度が一気に向上
2010年:OSGi R4.2の一部としてEnterprise Specification公開
 Java EE環境でOSGiを活用するための拡張仕様
 Spring Framework由来のDIコンテナ機能も標準化
7
OSGiの提供する機能




Moduleレイヤー
 依存関係の解決
 複数バージョンの管理
Life Cycleレイヤー
 モジュールの動的ロード
Serviceレイヤー
Securityレイヤー
実行環境が依存関係を管理
異なるモジュールが
同一モジュールの異なるバージョンを
要求してもOK
JVMを起動したまま
モジュールの入れ替えが可能
8
Bundle: OSGiにおけるモジュール
JAR
+
OSGi
Metadata
META-INF/MANIFEST.MF
9
OSGi Metadata
Manifest-Version: 1.0
Export-Package: org.apache.aries.samples.blueprint.helloworld.server;
uses:="org.apache.aries.samples.blueprint.helloworld.api";
version="0.2.0.incubating"
Import-Package:
org.apache.aries.samples.blueprint.helloworld.api;version="[0.2,0.3)"
Implementation-Title: Apache Aries
Implementation-Version: 0.2-incubating
Bundle-Name: Apache Aries Blueprint HelloWorldServer
Bundle-SymbolicName: org.apache.aries.samples.blueprint.helloworld.server
Bundle-Vendor: The Apache Software Foundation
Build-Jdk: 1.6.0_21
Bundle-Version: 0.2.0.incubating
Bundle-ManifestVersion: 2
Bundle-Description: Example blueprint hello world application - server
Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
Bundle-DocURL: http://www.apache.org
10
バージョン管理
Export
Import < 1.4.0
1.2.0≦ バージョン
com.foo.bar
com.foo.bar
1.4.5
[1.2.0, 1.4.0)
両方のBundleに同名のClass
が存在していても、正しく解決
される
com.foo.bar
com.foo.bar
1.3.12
[1.4.0, 1.5.0)
11
Bunldeのライフサイクルと依存関係の解決
Bundleをstartすると、"Starting"
を経て"Active"に
OSGi FrameworkにBundle
をロードすると"Installed"に
Bundleをstopすると、
"Stopping"を経て"Resolved"に
戻る
Import-Packageなどで指定された依
存関係を満たすかチェック
⇒OKなら"Resolved"に
12
ライフサイクル・サービス
Bundleの状態が変化したとき
に、Frameworkからコールバッ
クされる
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class MyAppActivator implements BundleActivator {
public void start(BundleContext context) throws Exception {
System.out.println("Bundle is starting.");
}
public void stop(BundleContext context) throws Exception {
System.out.println("Bundle is stopping.");
}
}
13
バージョン管理: behind the scenes
Export
Import
com.foo.bar
com.foo.bar
1.4.5
[1.2.0, 1.4.0)
com.foo.bar
com.foo.bar
1.3.12
[1.4.0, 1.5.0)
FrameworkがBundle毎に
ClassLoaderを作成し、
Metadataに従って関連付ける
14
ClassLoader
めでたし、めでたし?


ここまでの話で「おや?」と思った方、鋭い!
実はまだ問題があります。。。整理してみましょう。




Bundle間の依存関係の解決は、Bundleをロードした後に行わ
れる
無事に依存関係が解決できると、Bundle毎のクラスローダー
が関連づけられ、"Resolved"に
Bundleをstartすると"Active"になって動作する
では、既にActiveになっているBundleの新しいバージョン
をリリースするには、どうすれば?
15
Bundleのバージョンアップ?
Export
<<active>>
Import
<<active>>
com.foo.bar
com.foo.bar
1.4.5
[1.4.0, 1.5.0)
install/start
com.foo.bar
1.4.6
16
Client Bundleをstop/startしな
い限り、新しいバージョンとの
紐付けは行われない
実は・・・



Export-Package/Import-Packageによる参照は
「静的な参照」関係
依存関係の解決は、Bundleをstartした時にOSGi
FrameworkにロードされているBundleに対して行われる
依存関係を更新するためには、Bundleを再起動する必
要あり
この方法では、
動的なモジュールの交換は不可能
(涙)
17
では、動的なモジュールの交換はどうする?


そのための仕組みが、OSGi Frameworkの提供する
Service Registryです
Serviceと言っても大げさなものではなく、実体はJavaの
Class(Interface)です
Registryから毎回lookupするの
Service
Registry
register
Service
Provider
18
で、更新されたバージョンが登
録されていれば直ちに反映さ
れる
lookup
Service
Requester
Serviceの登録と参照
public class GreetingImple implements Greeting {
・・・・・・・
}
Serviceの登録
public class Activator implements BundleActivator {
public void start(BundleContext ctx) {
ctx.registerService(Greeting.class.getName(),
new GreetingImpl("service"), null);
}
・・・・
Interfaceのクラス名で、
GreetingImplのインスタンスを
登録
Serviceの参照
public class Client implements BundleActivator {
Interfaceのクラス名で、サービ
public void start(BundleContext ctx) {
スのインスタンスを取得
ServiceReference ref =
ctx.getServiceReference(Greeting.class.getName());
((Greeting) ctx.getService(ref)).sayHello();
}
・・・・
19
OSGi R4.2 Enterprise Specification

OSGi Alliance Enterprise Expert Group(EEG)によって
定められたEnterprise向けの拡張仕様


http://www.infoq.com/news/2010/03/osgi-enterprise-42released
以下が規定されている



アプリケーションのアセンブリ・フォーマットの拡張
JavaEEコンテナ・サービスとの統合
宣言的なDI仕様(Blueprint)
OSGi化したエンタープライズ・アプリケーション
OSGi
metadata
OSGi
Bundle
OSGi
Bundle
OSGi
Bundle
(.jar)
(.jar)
(.jar)
Web App
Bundle (.wab)
Business
Level
Application
Enterprise
Bundle App
(.eba)
Context
Path
Virtual
Host
Enterprise Bundle App (.eba)
21
Blueprint component model


サービスレジストリへの登録や参照を宣言的に行うための仕様
JNDIサービスにより、OSGiのサービスレジストリにJNDI経由でアクセス可能
[OSGI-INF/blueprint/service.xml]
OSGi Bundle
(.jar)
<blueprint
xmlns:tx="http://www.ibm.com/appserver/schemas/8.0/blueprint/transactions"
xmlns:jpa="http://www.ibm.com/xmlns/ibm-blueprint-jpa/v1.0.0">
<bean id="blabberImpl" class="com.ibm.ws.eba.example.blabber.persistence.BlabberImpl">
<jpa:context property="entityManager" unitname="blabber" />
<tx:transaction method="*" value="Required"/>
Interface名で実装(bean)を公開
</bean>
<service id="blabberService" ref="blabberImpl"
interface="com.ibm.ws.eba.example.blabber.persistence.spi.BlabberUserInterface" />
</blueprint>
OSGiサービス・レジストリーから
Interface名で実装(bean)を取得
Client
InitialContext ic = new InitialContext();
return (BlabberUserInterface) ic.lookup("osgi:service/" +
BlabberUserInterface.class.getName());
ちょっと宣伝:
WAS V7 Feature Pack for OSGi Applications
http://www.ibm.com/software/jp/websphere/apptransaction/was/featurepacks/osgi/
WASの上で動くアプリケーションも"OSGi Bundle"に
Apache Foundationに寄贈され
Incubatorでオープンソース化の作業中
23
OSGiって何がうれしいの?(その1)

設計モデルと実行モデルの一致
実行モデル
フラットなClass Loader
実行モデル(Java)
設計モデル
non-OSGi
設計モデル
B.jar
A.jar
B.jar
A.jar
設計時に意図し
ていない参照の
リスク
C.jar
バンドル毎のClass Loader
実行モデル(OSGi)
C.jar
OSGi
依存関係を明示
することで設計
時の意図を遵守
B.jar
A.jar
C.jar
OSGiってなにがうれしいの?(その2)

依存関係のトレーサビリティ
A.jar
C.jar
E.jar
モジュールを入れ替える際に
影響を受けるモジュールが
機械的に特定できる
B.jar
D.jar
F.jar
G.jar
GrailsとOSGi

Grails 2.0 Roadmap

26
http://www.grails.org/Roadmap
意味がわからないので、翻訳してみた
よくわからんけど、要はGrailsのプラグインを
OSGi Bundleにするよってことかな?
27
GrailsプラグインをOSGi化する理由は?



すいません、プラグイン作ったことないので。。。
妄想してみます。
おそらく、以下のような課題があるのでしょう




プラグイン間の依存関係がよく壊れて動かなくなる?
同一プラグインの複数バージョンを同時にデプロイできない?
アプリケーションを稼働させたまま、サービスモジュールを入
れ替えることができない?(いわゆる活性保守)
Grails2.0のブランチはまだ作成されていないので、どうな
るかまったく予想がつきません。
28
待ちきれないよ!!!!

そんなあなたにお勧め、Grails OSGi plugin


http://www.grails.org/plugin/osgi
GrailsアプリケーションをBundle化して実行できます


29
grails bundle
grails run-bundle
まとめると・・・

OSGiって最近よく聞くけど、いったい何者?


それは美味しいですか?


そんなことはないです。むしろ、大規模開発ではアーキテクトと開発者と基盤担当
者の共同作業をやりやすくしてくれます。
僕らに何か関係あるんですか?

Grails2.0のプラグインシステムはOSGiベースになるみたいですよ。
SpringSourceもOSGiに力をいれてますよ。

今は知ってる人が少ないからチャンスかも。。。。。


正直、万人向けのお味ではありませんが、
慣れるとやみつきになります。
それは開発者を苦しめる新たなバズワードですか?


モジュラーJavaのプラットフォームです。
関係ないけどガンダムUCは商業ベースの同人作品?

30
そうです。
面白ければいいぢゃないですか!ね、@bikisuke さん。
参考資料(宣伝成分多めですが・・・)





OSGi R4.2 仕様書
 http://www.osgi.org/Download/Release4V42
Introduction to OSGi by Neil Bartlett
 http://www.slideshare.net/njbartlett/introduction-to-osgi-tokyo-jug
dW:エンタープライズOSGi入門
 第1回 OSGi概要と実行環境の導入
http://www.ibm.com/developerworks/jp/websphere/library/was/was7_fep_osgi/1.html
 第2回 OSGiのエンタープライズ拡張仕様を紐解く
http://www.ibm.com/developerworks/jp/websphere/library/was/was7_fep_osgi/2.html
 第3回 OSGiによるアプリケーションのモジュール化
http://www.ibm.com/developerworks/jp/websphere/library/was/was7_fep_osgi/3.html
RedBooks: Getting Started with the Feature Pack for OSGi Applications and JPA 2.0
 http://www.redbooks.ibm.com/abstracts/sg247911.html?Open
dW: OSGiアプリケーションを開発、利用するためのベスト・プラクティス
 http://www.ibm.com/developerworks/jp/websphere/library/was/was7_osgi_practices/
31
以上です。ありがとうございました。
32