The Apache Software Foundationのトップ・プロジェクトにAvalonがあるのをご存知だろうか。
AvalonといってもWindowsの次期OS(Longhorn)のプレゼンテーション技術や,アーサー王の話ではない。AvalonプロジェクトはFTPサーバーやHTTPサーバーのようなサーバー・アプリケーションをJavaで作成する場合のフレームワークを提供するプロジェクトだ。以前はJakartaプロジェクトにて開発が行われていたが,最近StrutsやAntと同様にApacheのトッププロジェクトとなった。
歴史が古い割には,Avalonは日本であまり知られていない。理由の1つとして,プロジェクトの巨大さがあるだろう。何をどう利用すればよいのかが非常に分かりずらかったのである。
Avalonの開発者たちは,それに気づき,2004年3月にプロジェクトを大胆に整理した。これにより,それまで開発していた,Phoenix,Excalibur,Cornerstoneなどの多くのプロダクトを非推奨とし,コンポーネント・コンテナ「Merlin」にノウハウのすべてを集約した。これにより,Avalonは非常に理解しやすく導入しやすいプロジェクトに変わった。
3つのサブプロジェクトFramework,Merlin,phoenix
Avalonの歴史は,Apache Tomcatの前身であるApache JServを開発中に,サーバー・フレームワークの可能性を見出した数人のコミッタが,1999年にJava Apache Server Frameworkと呼ばれるプロジェクトを提案したことから始まる。このプロジェクトの目的は,Apache内の各サーバー・プロジェクトのベースとなりうるフレームワークを提供することだった。このプロジェクトが現在のAvalonプロジェクトとなった。
現在のAvalon内には3つのサブプロジェクトが存在し,様々なプロダクトを開発している。前述のプロジェクトの整理によって,以前提供していたフレームワークphoenixや,コンポーネント群のCornerstoneや, Excaliburは非推奨となり,新しいプロダクトとして整理された。
現在のAvalon内には
Avalonプロジェクトのベースであり,設計思想やデザイン・パターンとそれらをベースに実装した様々なAPIを提供
コンポーネント・コンテナで,Avalonのリファレンス・インプリメンテーション
いくつかのコンポーネント・グループを統括するプロジェクト。各コンポーネント・グループでは数多くのコンポーネントが開発されている
の3つのサブプロジェクトが存在している。
アプリの土台,機能部品,コンテナを提供
Avalonは,上記のサブプロジェクトからも分かるとおり,サーバー・アプリケーションを構築するための様々なプロダクトと設計思想を提供している。
Avalonは,サーバー・サイドで動作するアプリケーションの土台(フレームワークおよびAPI)と,サーバー・アプリケーションに必要な機能部品(コンポーネント),それを管理するコンテナのみを提供する。そのため,どのようなアプリケーションにも適用できる。
Avalonを用いてアプリケーションを作成する場合,単独利用可能なコンポーネントを利用する方法と,独自のコンポーネントを作成しコンテナに登録する方法がある。コンテナを利用する場合,登録するコンポーネントの機能に制限はない。Javaサーブレットのようなプレゼンテーションを生成するアプリケーションも,DNSサーバーのような通信プロトコルに基づくサーバー・アプリケーションも登録できる。
このコンポーネント・コンテナは,EJBコンテナの代わりとして利用することも可能だ。EJBの代わりにビジネスロジックをコンポーネントとして実装し,コンポーネント・コンテナであるMerlinに配置するという方法だ。この利用方法は,ビジネス・ロジックや,データベース・アクセス部分をカバーする方法で,ちょうどStrutsがカバーしていない領域を補うことができ,相性がよい。
特徴は,コンポーネント指向とDependency Injection
Avalonはサーバー・プログラム用のフレームワークを提供することを目的に開発が行われているが,その設計方針はコンポーネント指向と,Dependency Injection(依存性注入)というパターンに基づいている。Avalonは単にソフトウエア・プロダクトを提供するだけではなく,設計思想やデザイン・パターンまでも提供しているのだ。
以降では代表的な2つを説明するが,この他にも様々な情報がサイト内で提供されている。
コンポーネント指向とは,コンポーネント(単独でも動作可能な,一定の機能単位で提供されるソフトウエアの塊)を組み合わせることで,アプリケーションを構成する設計思想だ。Avalonには思想の提供だけでなく,サーバー・アプリケーションを作成する際に必要となる数多くのコンポーネントが実際に提供されている。そして,このコンポーネントを組み合わせる際のパターンとして,Dependency Injectionが採用されている。
Dependency Injectionはデザイン・パターンの一種だ。Avalonプロジェクトでは,IoC(Inversion of Control),「制御の反転」という呼び方で表現している。このパターンはMartin Fowlerらによって,その目的をより具体化したDependency Injection(依存性注入)という名前がつけられた。このDependency Injectionは最近注目をあつめている軽量コンテナのPicoContainerやSpringでも採用されたが,Avalonでは古くからこのパターンを採用していた。
Dependency Injectionの目的は,協調して動作する複数のコンポーネント間の依存を疎にしておくことで,各コンポーネントの再利用性を高めようというものだ。コンポーネント間の依存度が下がることで,コンポーネントの自由な組み合わせが可能となり,機能拡張や変更が行いやすくなるといった利点がある。具体的には,あるコンポーネントが利用する別のコンポーネントは,内部で生成するのではなく,外部から注入(Inject)してもらうということだ。注入の作業をするものはAssemblerと呼ばれ,コンポーネントとは独立して存在させる。
これらの実装例を,Avalonプロジェクトのコンポーネント指向の説明用サンプル(http://avalon.apache.org/framework/cop/guide-patterns-ioc.html)を例に説明する。
interface LogEnabled {
public
enableLogging(Logger newLogger);
}
class MyComponent
implements LogEnabled
{
Logger
logger;
public enableLogging(Logger
newLogger)
{
this.logger = newLogger;
}
myMethod()
{
logger.info("Hello
World!");
}
}
サンプルは,コンポーネントMyComponentがログ出力を行う場合を題材にしている。ログ出力はメソッドmyMethod内で,Loggerインタフェースをもったオブジェクトloggerに対して行われている。コードでは,このオブジェクトloggerは,MyComponentの内部でインスタンスを生成するのでも,Factoryパターンなどで得るのでもなく,メソッドenabledLoggingを通して与えられている(注入されている)のが分かると思う。
このように,利用するコンポーネントを外部から必ず注入してもらうというパターンがDependency Injectionパターンである。Dependency Injectionパターンはコンポーネントを外部から注入する方法によって,3つの形式に分類されている。Type1 IoC(インタフェース・インジェクション),Type2 IoC(セッター・インジェクション),Type3 IoC(コンストラクタ・インジェクション)である。サンプルではインタフェースLogEnabledで注入のためのインタフェース(インジェクション・インタフェースと呼ぶ)が定義されているので,この方式はType1 IoCということになる。AvalonではこのType1 IoCが採用されている。
Avalonプロジェクトでは,これらのDependency Injectionパターンとコンポーネント指向を採用することで,アプリケーションの拡張性やメンテナンス性を確保している。
数多くプロダクトで構成されるAvalonの全体像
Avalonはその長い歴史から,多くのプロダクトを生み出してきた。また,コンポーネント指向という性格上,数多くのコンポーネントや方法論が存在し,非常に巨大なプロジェクトとなりサイトを見ただけではその全体像がつかみにくかった。
しかし前述のようにサブプロジェクトを分割・整理したことで,わかりやすい構成になった。プロジェクト・サイトの構造もそれにあわせて一新された。参考までに,新しいサイトの代表的なページを紹介しておく。これまでの説明を加味して見れば,全体像がわかってくることと思う。
- Avalon Project
- Framework
- Avalon Framework API and Implementation
- Component Oriented
- Component Development
- Avalon Meta
- Avalon Utilities
- Criteria
- Defaults
- Environment
- Exception
- Extension
- Avalon Repository
- Avalon Logkit
- Merlin
- Getting Started
- Installation
- Using Merlin
- Advanced Features
- Merlin System
- Object Model
- Subsystems
- Embedding
- Extensions
- Platform Tools
- Facilities
- Tools
- MerlinPlugin for Maven
-Planet
- Cornerstone Collection
- Components
- Excalibur Utilities
- Third-Party Components
表からも,数多くのプロダクトが存在していることが分かると思う。Avalonが生み出したプロダクトで有名なものに,LogkitとPhoenixがあげられる。Logkitはログ出力を行うコンポーネントで,単体でも利用できる。Apacheのロギング・フレームワークcommons-loggingでも,Log4Jと同様にログ出力パッケージの選択肢の1つとして採用されている。
Phoenixは,サーバー・アプリケーションを作成するためのカーネルである。Phoenixを採用したアプリケーションには,XML文書変換サービスのApache Cocoonや,前回ご紹介したメール・アプリケーション・サーバーApache Jamesなどがある。その他にも多くのサーバー・アプリケーションがPhoenixを採用しているが,Phoenixは前述の通り,非推奨となった。その代わりに現在ではMerlinというコンテナが提供されている。
コンポーネントを管理するコンテナMerlin
Merlinは,Assemblerエンジンをベースにした,コンポーネントを管理するコンテナであり,Avalonの参照実装(リファレンス・インプリメンテーション)だ。Avalonのフレームワークに則って作成されたコンポーネントはMerlin内に配備でき,アプリケーションの一部として動作可能となる。J2EEアプリケーションにあてはめてそれぞれを説明すると,J2EEの各APIおよびその実装が Avalon Framework,EJBコンテナがMerlin,EJBが各コンポーネントに相当すると考えればよいだろう。
Avalonは,これまでにもECM(Excalibur Component Manager)やFortress,Phoenixといったコンポーネント管理システム(コンテナやフレームワーク)を提供してきたが,複数のコンポーネント管理システムの提供は,利用者への混乱とメンテナンス性の低下をもたらすため,それらは非推奨となり2004年3月にMerlinに一本化された。
Merlinは,コンポーネントのセットによって構成されるサービスのカプセル化を支援するコンポーネント・コンテナだ。Merlinを利用すると,アプリケーションが提供するサービスから,それを実装するコンポーネントの実装方式を分離することが可能となる。Merlinの最終目標はネットワーク上に分散配置したMerlinを連携させてシステムが構築できるようになることだが,残念ながら現在はそこまで至っていない。
しかしながら,Merlinは現時点のAvalonプロジェクトの集大成として,様々なメリットをもたらしてくれる。次回はこのMerlinの概要と利用法について説明したいと思う。
■著者紹介
黒住幸光(くろずみ ゆきみつ)氏
株式会社アークシステム
システム構築スペシャリスト。1995年,スーパー・コンピュータ向け言語処理環境の研究中に,生まれて間もないJavaと出会う。のちにJavaに専念するため転職を決意。現在,株式会社アークシステムにてオープンソース・ソフトウエアを用いたWWWシステムの構築,コンサルティングを行うかたわら,雑誌への執筆,StrutsユーザーMLの管理,Ja-JakartaプロジェクトTurbine翻訳の取りまとめなど幅広く活動中。メール・アドレスは,mailto:yukimi_2@yahoo.co.jp