第4章 EJB3 サービスと Enterprise Application

EJB3 (Enterprise Java Bean 3.0) は、Java EE 5 アプリケーションのコアとなるコンポーネントモデルを提供します。EJB3 bean は、管理コンポーネントでトランザクション、セキュリティ、永続性、ネーミング、依存性注入など Java EE 5 サーバーコンテナーが提供するサービスすべてを有効活用できるよう自動的にワイヤーされている管理コンポーネントです。この管理コンポーネントにより、開発者はビジネスロジックに集中し、横断的関心事 (cross-cutting concern) はコンテナーに設定として任せることができます。アプリケーション開発者として、コンポーネントの作成や破棄はご自身で行う必要があります。Java EE コンテナーから EJB3 bean の名前のみで EJB3 bean を呼び出しでき、適用した設定済みのコンテナーサービスすべてを使いメソッドを呼び出すことができます。Java EE コンテナーの内部、外部を問わず EJB3 bean へアクセスできます。
JBoss Enterprise Application Platform 5 はカスタマイズなしに EJB3 に対応しています。JBoss Enterprise Application Platform 4.2 は J2EE サーバーであるため、EJB3 機能セットすべてに対応していない点に注意してください。
EJB3 コンポーネントのプログラミングモデルに関する詳細は、本書の対応範囲を超えています。EJB3 インターフェースとアノテーションのほとんどが Java EE 5 規格の一部であるため、Java EE 5 準拠の全アプリケーションサーバーと同じです。興味のある方は EJB3 仕様か、EJB3 関連の本が多数ありますのでそちらを参照し、EJB3 プログラミングについて学習してみてください。
本章では、JBoss Enterprise Application Platform 固有となる、EJB3 設定の問題について見ていきます。例えば、JBoss Enterprise Application Platform における EJB3 コンポーネントの JNDI 命名規則、エンティティ bean 向けの Hibernate 永続エンジンのオプション設定、JBoss EJB3 デプロイヤーのカスタムオプションについて触れています。

4.1. セッション bean

セッション bean は、ローカルおよびリモートクライアントにトランザクションサービスを提供する際に幅広く利用されています。セッション bean を記述するには、インターフェースと実装クラスが必要になります。

@Local
public interface MyBeanInt {
  public String doSomething (String para1, int para2);
}

@Stateless
public class MyBean implements MyBeanInt {

  public String doSomething (String para1, int para2) {
    ... implement the logic ...
  } 
  
}    

セッション bean メソッドを呼び出すと、サーバーにあるセキュリティーマネージャーとトランザクションマネージャーがメソッド実行を自動的に管理します。メソッド上のアノテーションを使うことで、メソッド毎にトランザクションあるいはセキュリティプロパティを指定することができます。多くのクライアントで、セッション bean インスタンスを再利用することができます。サーバーが2つのクライアント間で bean の内部ステータスを管理するかどうかにより、セッション bean はステートレスかステートフルか決まります。Bean にリモートビジネスインターフェースがある場合、現在の JVM の外にあるクライアントは、EJB3 bean を呼び出すことができます。これらはすべて bean 上の標準のアノテーションを使い設定可能です。トランザクションあるいはセキュリティプロパティは、Bean がビジネスインターフェースから呼び出された場合のみ有効である点に注意してください。
セッション bean を定義後、クライアントはどのようにそのセッション bean への参照を取得するのでしょうか?前述したとおり、クライアントは、EJB3 コンポーネントを作成あるいは破棄しないため、サーバーが管理している既存のインスタンスへの参照をサーバーに要求するだけです。これは、JNDI 経由でできます。JBoss AS では、セッション bean に対するデフォルトのローカル JNDI 名は bean クラスのデプロイメントパッケージにより変わります。
  • Bean が JBOSS_DIST/default/deploy にあるスタンドアローンの JAR ファイルにデプロイされた場合、Bean はローカルの JNDI 名 MyBean/local 経由でアクセス可能です。ここでは、先ほど示したように、MyBean は bean の実装クラス名です。JBoss AS では Local の JNDI は、java:comp/env/ を起点とする JNDI 名となります。
  • Bean を含む JAR ファイルが EAR ファイルにパッケージされている場合、Bean に対するローカルの JNDI 名は myapp/MyBean/localです。このmyapp はEAR アーカイブファイルのルート名となっています (例:myapp.ear。EJB3 bean の EAR パッケージについては本書で後述されていますので参照してください)。
Bean インタフェースに @Remote のアノテーションがついており、デプロイされているサーバーの外から Bean にアクセスする場合は、もちろん、localremote に変更するべきです。以下は、myapp.ear にパッケージされたWeb アプリケーションで MBean bean の参照を取得し、管理メソッドを呼び出すためのコードスニペットです (例:サーブレットあるいは JSF バッキング bean)。

try {
  InitialContext ctx = new InitialContext();
  MyBeanInt bean = (MyBeanInt) ctx.lookup("myapp/MyBean/local");
} catch (Exception e) {
  e.printStackTrace ();
}

... ...

String result = bean.doSomething("have fun", 1);

... ...

クライアントが JNDI から取得したものは必然的に、Bean インスタンスの「スタブ」あるいは「プロキシ」となります。クライアントがメソッドを呼び出すと、プロキシは、リクエストをサーバーまでどのようにルーティングし、レスポンスをあわせてマーシャリングするか見出します。
デフォルトの JNDI 名が気に入らない場合は、いつでも bean 実装クラスの @LocalBinding アノテーション を使い Bean に独自の JNDI バインディングを指定することが可能です。JNDI バインディングは常に、java:comp/env/ スペースの下では Local となります。例えば、以下の bean クラス定義は、java:comp/env/MyService/MyOwnNameという JNDI 名の下で利用可能な bean インスタンスが返ってきます。

@Stateless
@LocalBinding (jndiBinding="MyService/MyOwnName")
public class MyBean implements MyBeanInt {

  public String doSomething (String para1, int para2) {
    ... implement the logic ...
  } 
  
}    

注記

Java EE 5 は、明示的に JNDI ルックアップを行わずにアノテーションを使うことで、EJB3 bean インスタンスを直接、Web アプリケーションに注入できるようになります。この動作は、JBoss Enterprise Application Platform 4.2 では未対応ですが、JBoss Enterprise Platform は、JBoss Seam と呼ばれる統合フレームワークを提供しています。JBoss Seam では、Java EE 5 が提供しているものをはるかに超える新たなレベルで、EJB3 / JSF 統合が行えます。詳細は、本プラットフォームに同梱されている JBoss Seam のリファレンスガイドを参照してください。