Seam2からJavaEE6へ移行するには

Seam2ベースのアプリケーションをJava EE6へ移行する方法について考えます。

JBoss Developer Framework (JDF) はJBoss.orgで公開されているJBoss上での開発支援のためのサイトで、ドキュメンテーションやたくさんのサンプルが提供されています。このサイトにSeam2からCDIへの移行についてのページがあります(JBoss Developer FrameworkについてはInfoQの記事をご覧ください)。このページに書かれていることについて私の解釈を書いてみます。

上のページを見るとSeam2の移行についていくつかのシナリオが提案されています。Seam2を使い続ける、Java EE6に対応したSeam 2.3に移行する、Seam2をすべてCDIベースに書き換える、という中での選択です。ここでは、CDIへの移行という観点から最後のシナリオについて考えてみます(Seam2の移行先にSeam3は含まれません。そもそも、Seam2とSeam3はまったく別物であり、Seam3はDeltaSpikeに移行することが決まって現在はメンテナンスフェーズなので移行するメリットが無いからです)。

最後のシナリオの課題は移行にあたってSeamアプリケーションの修正が必要ということです。CDI仕様は、このブログを読んでいる方にとっては改めて説明するまでもありませんが、Seam 2のコアモデルをベースにしてJSR-299としてJava EE仕様としてまとめられたものです。このCDI仕様は、Seam2がベースになっているので基本的な考え方はもちろん近いのですが、CDIでは「タイプセーフによる疎結合」というテーマのもとでSeam2のモデルから変更されたために、出来上がったAPIの互換性は無くなっています。

私は主なコアモデルの違いは次のようなものだと考えています。

  • SeamとCDIのアノテーションが異なる(例:@In →@Inject)
  • SeamとCDIは類似のスコープを提供するが個々のスコープの定義・機能はSeamと完全に同一ではない
  • SeamとCDIは両方ともConversationスコープを提供するが、CDIのConversationはネストできないなど機能的には同一ではない
  • Seamではコンポーネント名(文字列)ベースのインジェクションであったが、CDIでは型に基づくタイプセーフなインジェクション
  • Seamではイベントは名前に基づいていたが、CDIではタイプセーフな方法でイベントの送受信が可能
  • Seamではメソッド実行時にインジェクションが行われるが(動的)、CDIではインスタンス生成時に行われる(静的)
  • SeamのアウトジェクションはCDIでは存在せず、代わりに動的な値の生成には(Seam2 のファクトリに近い)プロデューサが導入された
  • Seamではモジュールの拡張性が乏しかったが、CDIでは拡張モジュールSPIを提供しているので標準的な方法でCDI機能を拡張することができる

SeamからCDIへ移行する最大のメリットはそれ自身がJava EE仕様に含まれる標準であるということです。また、CDIはタイプセーフなので、インジェクションされるBeanが適切かどうかはコンパイル時に検出されます。これは、Seamのインジェクションが実行時に行われるために、@Nameで間違った名前を指定したときには実行時エラーになるのとは対照的です。

さらに、CDIではCDIを拡張するSPIが提供されているために、Seamで提供されていた各種便利コンポーネントを標準的な方法で開発することができます。「標準的な」という意味は、JBossのCDI実装ではない、別のCDI実装上でも同じCDI拡張が動作するということで、これによってJava EEのスペックを満たすアプリサーバー上でCDI拡張が流通可能になることを示しています。これは非常に強力な機能で、将来、EJBやJMSのような各種Java EE上のサービスをCDI上に再構築できることを暗示しています。

このようにSeamからCDIへ移行するということは、標準的な方法でコンポーネントの移植性と拡張性を手に入れることができるということになります。JSFとEJB、JPAの連携を行うだけであればCDI仕様の範囲内で開発できるでしょう。ところが、CDIはインジェクションのためのコンテナであって、Seamが提供する便利なコンポーネント群を使っている場合はそのコンポーネントの移行を検討する必要があります。Seamコンポーネントに対応するコンポーネントがJava EE上に存在しない場合は、それに相当する機能をアプリケーションが作り込む必要あるということです。ここで登場するのが当ブログで何度も紹介しているApache DeltaSpikeです。

Apache DeltaSpikeはCDI上で利用できるCDI拡張コンポーネントの集合体です。DeltaSpikeはSeamコンポーネントと同等の機能を実現することを目標としたプロジェクトではないので、コンポーネントの名前や機能、APIはSeamと互換性はありません。しかし、DeltaSpikeはアプリケーションが便利に使える汎用的なコンポーネントを提供するので、将来的にはSeamコンポーネントの代替となるコンポーネントが提供されるかもしれません。現在、DeltaSpikeはバージョン0.4を開発中です。0.3までは、DeltaSpikeのコンポーネントを開発するための共通の土台(ベース)の部分を開発してきました。0.4ではJSFやJPAのコンポーネント開発に着手しています。

DeltaSpikeのベース部分のSPIが安定すれば、Seam3のコンポーネントや他のOSSベースのCDI拡張がDeltaSpikeの上に移植しやすくなります(安定しないうちに多くのコンポーネントの移植するのは生産性が低く、無謀です)。他のCDI拡張をDeltaSpike上に移植することで、DeltaSpikeコンポーネントは徐々に充実していくことでしょう。しかし、DeltaSpikeが1.0になるまではまだしばらく時間がかかりそうです。

まとめると、Seam2からCDIへの移行を検討するにあたり、最初にSeamのどのコンポーネントを使っているかを整理するのがよいと思います。JSFとEJB/JPAのつなぎにSeam Conversationを使いたいというのであればJava EE仕様(+RichFaces)で移植を行うことも可能かもしれません。そうでない場合、つまりSeamのMailやi18N, JMS, Remoting, Transaction, Excelなどの便利コンポーネントを使っている場合はDeltaSpikeから同様のコンポーネントが提供されるのを待つか、CDI 拡張SPIを使って自前でそれを開発するという選択になるでしょう。これが冒頭で紹介したJDFのページが言わんとしていることだと思います。

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。