水曜日 11 29, 2006

Seam without EJB3. Any J2EE 1.4 servlet container, even Tomcat, is supported!

先日、JBoss Seamの1.1CR版がリリースされましたが、Seam 1.1からはEJB3コンテナ機能がなくてもSeamを利用できるようになったそうです。

最初は、Embeddable EJB 3.0を使って実現しているのだろうと思っていたのですが、そうではありませんでした。Seamのアクション・クラスは従来@Statelessまたは@Statefulアノーテーションを付与したセッション・ビーンとして定義する必要がありましたが、1.1ではWebコンテナで動作するPOJOとして定義できるようになりました。

これにより、SeamはJ2EE 1.4仕様のWebコンテナさえあれば動作させることができるようになったため、現時点で選択可能なプラットフォームが広がり、Apache Tomcat上でも実行できるようになったことは興味深いことです。

この仕様変更によるもう一つの重要な点は、Seamのアクション・クラスが本来のJSFバッキング・ビーンとしての役割により近付いたということができます。より正確に言うと、将来のJSF仕様のあるべき姿をもっとも好ましい形で実現するようになったと言えます。

Java EE 5仕様がEoD(Ease of Development)目標に対して大きく進化した中で、Java EE 5に含まれるJSFの仕様変更は僅かでした。例えば、Java EE 5のDI(Dependency Injection)はアノーテーションを利用することで、XMLを記述しなくてもオブジェクト間のワイヤリングが行なえます。JSFにはバッキングビーンとページの入出力となるモデルオブジェクトをワイヤリングするためのDIコンテナとしての機能がありますが、Java EE 5仕様になっても、アノーテーションによるJSFマネージド・ビーンのワイヤリングは実現されませんでした。ビーン間の関連を定義するには、従来通りfaces-config.xmlのタグでオブジェクト間の関連を定義する必要があります。例えば、ユーザに関する入力パラメータを保持するUserオブジェクトをHTTP POSTされたときに実行されるバッキングビーンRegisterBeanにインジェクションする場合、JSF仕様だけを使用した場合には以下のような定義が必要でした。

 <faces-config>
  <managed-bean>
    <managed-bean-name>register</managed-bean-name>
    <managed-bean-class>com.example.web.RegisterBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <managed-property>
      <property-name>user</property-name>
      <value>#{user}</value>
    </managed-property>
  </managed-bean>

  <managed-bean>
    <managed-bean-name>user</managed-bean-name>
    <managed-bean-class>com.example.web.User</managed-bean-class>
    <managed-bean-scope>none</managed-bean-scope>
  </managed-bean>
</faces-config>

Seamでは、上記のような煩わしいfaces-config.xmlを記述する代わりにソースコード中のアノーテーションで上記とほぼ同等のメタ情報を与えることができます。

//@Stateless               ← セッションビーンである必要はない
@Name("register")
public class RegisterBean
// implements Register     ← セッションビーンでないため、インタフェースも不用
{
   @In                  // ← 名前"user"のビーンをインジェクション
   private User user;
   
   public String register() {...}
}

ちょうど、managed-bean-nameタグを@Nameで、managed-bean-propertyタグを@In(または@Out)で代用したものと考えてよいでしょう。しかし、@Nameや@Inはfaces-config.xmlの自動生成に使われているのではありません。Seamでは、ビーンのライフサイクルを拡張しているため、独自マイクロコンテナによってビーンのライフサイクルを管理しています。特に、標準のJSFでは定義できない対話(conversation)スコープやビジネス・プロセスのためのスコープを定義できることは非常に重要です。

しかし、SeamアクションクラスをPOJOにした場合、セッション・ビーンとして実現した場合の全ての機能が利用できるわけではないようです。"JBoss Seam for J2EE Developers II: Examples and Configurations"をみると、SeamアクションをPOJOにマッピングした場合に利用できなくなる機能は以下のようになります。

  • @PersistenceContextによるEntityManagerのインジェクション(おそらく、@ResourceなどJava EE 5で導入されたインジェクション用のアノーテションの全て)はできない。その代わり、EntityManagerのワイヤリングには、@Inアノーテーションを使用する。
  • @TransactionAttributeによるメソッド毎のトランザクション属性の設定はできない。その代わり、Webページがレンダリングされた後にコミットされるようにSeamを構成することができる。
  • MDBと同等の機能をPOJOで実現することはできない。
  • @Asynchronousはサポートされない。
  • @RollesAllowedなどによるコンテナ管理セキュリティ
  • EntityManagerのライフサイクルをトランザクション・スコープにすることはできない。全てのEntityManagerのスコープは"extended"でありconversationとなる。
  • JMXとの統合機能はない。
  • POJOをRMIでリモート呼び出しすることはできない。
  • POJOを@WebServiceでWebサービス化することはできない。
  • JCAとの統合機能はない。

上記の制約のいくつかはWebコンテナがJ2EE 1.4であることに起因するものであり、残りはEJBコンテナに依存する機能が利用できなくなることに起因するものです。一見、かなりの機能が利用できなくなったかのように見えますが、データベースへの読み書きしかしないような単純なWebアプリケーションであれば、EJBが不要であるケースもあります。それよりも、Tomcatをコンテナにした場合でも対話状態(conversational state)管理が手軽に利用できるようになったメリットの方が大きいでしょう。

Seam 1.0はBPMを使うような複雑なアプリケーションにも耐えうることを目標にしていたため、Java EE 5のフルスペックを要求するような仕様になってしまっていました。Seam 1.1では、「簡単なことはより簡単に」実現できるようになったため、簡単で小さなアプリケーションからエンタープライズレベルの複雑なシステムまで、幅広く採用を検討できるようになったと思います。

Seam 1.1のその他の新しい機能については、Michael Yuanの以下のブログ・エントリを参照してください。

About

Takashi Nishigaya
Principal Consultant
Technology Solution Consulting
Oracle Consulting Services

Search

Categories
Archives
« 4月 2014
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
今日