JSR 318: Enterprise JavaBeans 3.1

Enterprise JavaBeans 3.1(EJB 3.1)は現在Java EE 5に採用されているEJB 3.0の後継バージョンであり、次期Java EEプラットフォームとなるJava EE 6をターゲットとして仕様の策定が進められている。JCPでは2月29日よりEary Draftが公開されており、3月30日にかけてレビューが行われている段階だ。

バージョン2.xから3.0にかけては大幅な仕様の変更が行われたEJBだが、3.1はマイナー・バージョンアップであり、Early Draftによれば主に次のような機能が追加される予定となっている。

  • ローカルビジネスインタフェースなしでSession Beanにアクセスする簡易ビューの提供
  • Singleton Session Beanの導入
  • Session Beanの非同期呼び出しをサポート
  • EJBタイマーの自動生成
  • カレンダーベースの式によるEJBタイマーの作成
  • 軽量化されたEJB仕様のサブセット (EJB 3.1 lite) を提供
  • EJBコンポーネントを、ejb-jarを用いずにWARファイルにパッケージング可能に

以下に、いくつかの新機能の概略を紹介する。

Session Beanへの簡易ビュー

従来ローカルクライアントからSession Beanにアクセスするには、個別に定義されたローカルビジネスインタフェースを介する必要があった。EJB 3.1ではこれを簡潔にし、ビジネスインタフェースなしでもSession Beanのpublicなメソッドにアクセスできる簡易ビューが提供される。

インタフェースを持たないビューはビジネスインタフェースと同様にJNDI経由でEJBコンテキストから取得できる。コンテキストは対象となるBeanの型を持ったビューへの参照を返すが、クライアントからアクセスできるのはあくまでもpublicなメソッドだけであり、その他のメソッドにアクセスしようとした場合にはjavax.ejb.EJBExceptionがスローされるとのこと。また、Session Beanのインスタンスを (コンテキストを介さないで) 直接生成することもできない。

Singleton Session Bean

EJB 3.1ではSingleton Session Beanがサポートされる。Singleton Session Beanは複数のクライアント間で単一のインスタンスが共有されるSession Beanで、@Singletonアノテーションを用いるか、デプロイメントデスクリプタによって定義する。

Singleton Session Beanのインタフェースを持たないビューに対する参照は、常に同じオブジェクト識別子を持つ。したがってequalsメソッドによる比較は常にtrueとなる。ただし、異なるビジネスインタフェースタイプへの参照どうしや、インタフェースタイプへの参照とインタフェースを持たないビューへの参照、異なるSession Beanへの参照どうしの比較はtrueにはならない。

Session Beanの非同期呼び出し

デフォルトでは、Session Beanの呼び出しはすべて同期呼び出しである。すなわち、処理を開始してから値を返すまでの間、単一のクライアントによってブロックされる。それに対して、EJB 3.1からは非同期呼び出しもサポートされることになった。非同期呼び出しが可能なメソッド (非同期メソッド) は()@Asynchronousアノテーションによって作成し、戻り値は必ずvoidまたはjava.util.concurrent.Future<V>のインスタンスとする (Vは実行結果の型)。

リスト1 非同期メソッドの定義例 (Early Draftより抜粋)

@Asynchronous
public Future performCalculation( ... ) {
       // ... 計算を実行
       Integer result = ...;
       return new AsyncResult(result);
}

クライアントがSession Beanに対して非同期呼び出しを行った場合、コンテナはクライアントにコントロールを渡し、独立したスレッドにおいて処理を実行する。処理が完了したらFuture<V>のインスタンスが返されるので、クライアントではここからgetメソッドによって実行結果を取得したり、cancelメソッドによって処理の取り消しを行ったりすることができる。

EJBタイマーサービスの拡張

EJBタイマーサービスを利用するには、Beanクラスにコールバックメソッドを実装し、javax.ejb.TimerServiceのcreateTimerメソッドを用いてjavax.ejb.Timerインスタンスを生成する。このときcreateTimerメソッドにはタイマーの持続時間やインターバルをlong値やjava.util.Dateオブジェクトとして指定するのが従来の方法だった。これに対してEJB 3.1ではカレンダーベースの式よって指定する方法が追加されている。

この式はjavax.ejb.ScheduleExpressionのインスタンスとしてリスト2のように生成する。この例では毎週日曜日の午前1時に実行されるタイマーになるとのこと。

リスト2 ScheduleExpressionによるタイマー生成の例 (Early Draftより抜粋)

ScheduleExpression schedule =
    new ScheduleExpression().dayOfWeek(“Sat”).hour(1);
Timer timer = timerService.createTimer(schedule, null);

また、EJB 3.1ではTimerServiceを利用せずに、コンテナによってタイマーを自動生成する方法が提供される。その場合、コールバックメソッドは@Scheduleアノテーションを用いて作成し、タイマーの持続時間はアノテーションのパラメータで指定する。たとえばリスト3のようにすると、毎月1日の午前1時に処理を実行するタイマーが生成されるという。

リスト3 タイマーを自動生成する例 (Early Draftより抜粋)

@Schedule(hour=”1”, dayOfMonth=”1”)
public void generateMonthlyAccountStatements() { ... }

EJB 3.1(lite)

EJB 3.1では、フルセットの実装とは別に軽量化されたサブセットを提供しようという案が持ち上がっている。これはJava EE 6で導入が検討されているプロファイル機能に関連したものとなる。Java EE 6ではプロファイル機能によって、部分的な実装のみを含む機能制限されたJava EEプラットフォームを提供できるようになる予定。その際、一般的でない機能を省いた軽量プロファイルの提供も検討されており、EJB 3.1(lite)はそれを念頭に置いた提案である。

具体的にどの機能をEJB 3.1 (lite)に含めるかなどは現在議論されている最中だが、たとえばEJB 2.1スタイルのSession Beanなどを省略し、EJB 3.xのアノテーションベースのスタイルのみを利用可能にする、などといったことが考えられる。