EJB 非同期メソッドを呼び出すクライアント・コードの開発
このトピックにあるサンプル・コードを使用して、EJB 非同期メソッドを呼び出すクライアント・コードを開発することができます。
始める前に
public interface AcmeRemoteInterface {
void fireAndForgetMethod ();
Future<Integer> methodWithResults() throws AcmeException1, AcmeException2;
}
@Stateless
@Remote(AcmeRemoteInterface.class)
@Asynchronous
public class AcmeAsyncBean {
public void fireAndForgetMethod () {
// do non-critical work
}
public Integer methodWithResults() {
Integer result;
// do work, and then return results
return result;
}
}
このタスクについて
手順
- 結果が戻されない非同期メソッドを呼び出すクライアント・コードを作成します (このメソッドは応答不要送信 メソッドと呼ばれることもあります)。
このタイプの非同期メソッドはアプリケーション例外を生成できません。
ただし、解決しなければならないシステム例外が発生することはあります。
@EJB AcmeRemoteInterface myAsyncBean; try { myAsyncBean.fireAndForgetMethod(); } catch (EJBException ejbex) { // Asynchronous method never dispatched, handle system error }
- 結果が戻される非同期メソッドを呼び出すクライアント・コードを作成します。
- クライアントが結果を受け取るまで最大で 5 秒間待つ (クライアント・スレッドはこの時間の間ブロックされます) 非同期メソッドを呼び出すクライアント・コードを作成します。
例外処理要件は前のステップと同じです。
以下に例を示します。
myResult = myFutureResult.get(5, TimeUnit.SECONDS);
- 結果が即時に戻されない非同期メソッドを呼び出すクライアント・コードを作成します。
メソッドの実行完了後に、クライアントは結果を受け取ります。
このスキームはクライアント・スレッドがブロックされないようにするもので、クライアントは結果のポーリング中も自由に他の作業を実行することができます。
例外処理要件は先行するステップと同じです。
この例では、クライアントが定期的に Future<V> オブジェクトをポーリングして、非同期メソッドがいつ実行を完了したかを判別します。
以下に例を示します。
while (!myFutureResult.isDone()) { // Execute other work while waiting for the asynchronous method to complete. } // This call is guaranteed not to block because isDone returned true. myResult = myFutureResult.get();
- クライアントが結果を受け取るまで最大で 5 秒間待つ (クライアント・スレッドはこの時間の間ブロックされます) 非同期メソッドを呼び出すクライアント・コードを作成します。
例外処理要件は前のステップと同じです。
以下に例を示します。
- アプリケーション例外を処理するクライアント・コードを作成します。 このクライアント・コードは、Future<V> オブジェクトでアプリケーション例外を戻す非同期メソッドを呼び出します。
以下の例は、どのアプリケーション例外が発生したのかを判別するために必要な例外処理コードを示しています。
@EJB AcmeRemoteInterface myAsyncBean; Future<Integer>>myFutureResult = null; Integer myResult = null; try { myFutureResult = myAsyncBean.methodWithResults(); } catch (EJBException ejbx) { // Asynchronous method never dispatched, handle exception } // Method is eventually dispatched. Wait for results. try { myResult = myFutureResult.get(); } catch (ExecutionException ex) { // Determine which application exception that occurred during the // asynchronous method call. Throwable theCause = ex.getCause(); if (theCause instanceof AcmeException1) { // Handle AcmeException1 } else if (theCause instanceof AcmeException2) { // Handle AcmeException2 } else { // Handle other causes. } } catch ( ... ) { // Handle other exception. }
- 実行中に非同期メソッド呼び出しによってスローされたシステム例外を特定するクライアント・コードを作成します。
以下の例は、システム例外が発生したかどうかを判別するために必要な例外処理コードを示しています。
@EJB AcmeRemoteInterface myAsyncBean; Future<Integer>>myFutureResult = null; Integer myResult = null; try { myFutureResult = myAsyncBean.methodWithResults(); } catch (EJBException ejbx) { // Asynchronous method was not dispatched; handle exception. } // Method will eventually be dispatched so block now and wait for results try { myResult = myFutureResult.get(); } catch (ExecutionException ex) { // Find the exception class that occurred during the asynchronous method Throwable theCause = ex.getCause(); if (theCause instanceof EJBException) { // Handle the EJBException that might be wrapping a system exception // which occurred during the asynchronous method execution. Throwable theRootCause = theCause.getCause(); if (theRootCause != null) { // Handle the system exception } } else ... // handle other causes } catch (...) { // handle other exceptions }
- (オプション) 非同期メソッド呼び出しを取り消すクライアント・コードを作成します。
この試みが成功した場合は、Future.isCancelled メソッドが true を戻し、Future.get メソッドが CancellationException を生成します。 次の例は、非同期メソッド呼び出しを取り消すために必要なコードを示しています。
@EJB AcmeRemoteInterface myAsyncBean; Future<Integer> myFutureResult = myFutureResult.methodWithResults(); Integer myResult; if (myFutureResult.cancel(true)) { // Asynchronous method was not dispatched. } else { // Asynchronous method already started executing. The bean can still check // whether an attempt was made to cancel the call. } if (myFutureResult.isCancelled()) { // Asynchronous method call did not start executing because the cancel // method returned true in a previous line of the example. } try { myResult = myFutureResult.get(); } catch (CancellationException ex) { // Handle the exception that occurs because the cancel method returned true // in a previous line of the example. }
- (オプション) クライアントが非同期メソッド呼び出しの取り消しを試みたかどうかを調べる Bean コードを作成します。
次の例は、クライアントが非同期メソッド呼び出しの取り消しを試みたかどうかを調べるために必要な Bean コードを示しています。
クライアントがこの作業の取り消しを試みた場合は、SessionContext.wasCancelCalled メソッドが true を戻し、Bean コードは不要な作業を回避することができます。
@Resource SessionContext myContext; public Future<Integer> methodWithResults() { for (int i = 0; i < 3; i++) { // Do one piece of long-running work. // Before continuing, check whether the client attempted to cancel this work. if (myContext.wasCancelCalled()) { throw new AcmeCancelCalledException(); } } // ... }
- 非同期メソッド呼び出しからの複数の出力値を戻します。
場合によっては、1 つのメソッドで複数のデータを戻さなければならないことがあります。
このタスクを達成する方法の 1 つは、参照による受け渡しセマンティクスを使用することです。 このアプローチでは、オブジェクトがパラメーターとしてメソッドに渡され、メソッドによって更新された後、クライアントが更新された値を使用できるようになります。 このアプローチは非同期メソッドに有効ですが、最適なパターンではありません。
複数のデータを戻すには、このメソッドによって戻されるフューチャー・オブジェクトの中にラッパーを作成します。 このアプローチでは、戻さなければならないさまざまなデータを保持するインスタンス変数を含むラッパー・オブジェクトが定義されます。 非同期メソッドがこれらのデータをラッパー・オブジェクトに組み込み、ラッパー・オブジェクトを戻した後、クライアント・コードがフューチャー・オブジェクトからこのデータを取得します。
複数のデータをラッパー・オブジェクトの中に組み込むことは、いつ結果が得られるかを正確に識別するローカルまたはリモートの透過パターンです。 それに対して、従来の参照による受け渡し技法では、いつ結果が得られるかを判別する簡単な方法がクライアントに提供されません。 渡されたオブジェクトは非同期メソッドが実行されるまで更新されず、クライアントは、Future.isDone() または Future.get() メソッドを使用してフューチャー・オブジェクトに問い合わせない限り、いつ更新が行われたかを判別できません。
// This is the result object that is returned from the asynchronous method. // This object is wrappered in a Future object, and it contains the two pieces of data // that must be returned from the method. class ResultObject { public Boolean myResult; pubilc String myInfo; }
// This is the asynchronous method code that gets the results and returns them. @Asynchronous public Future<ResultObject> asyncMethod1(Object someInputData) { boolean result = doSomeStuff(); String info = doSomeMoreStuff(); ResultObject theResult = new ResultObject(); theResult.myResult = result; theResult.myInfo = info; return new javax.ejb.AsyncResult<ResultObject>(theResult); }
// This is the client code that obtains the ResultObject, and then extracts the needed data from it. Future<ResultObject> myFutureResult = myBeanRef.asyncMethod1(someInputData); ResultObject theResult = myFutureResult.get(); boolean didItWork = theResult.myResult; String explanation = theResult.myInfo;
サブトピック
EJB 非同期メソッドのクライアント・プログラミング・モデル
Enterprise JavaBeans (EJB) 3.1 仕様に規定されているように、 ローカル・ビジネス、リモート・ビジネス、またはインターフェースなしのビューの 3 つのタイプのインターフェースを 介して、EJB 非同期メソッドを呼び出すことができます。EJB 2.1 クライアント・ビューまたは Web サービス・ビューを介した呼び出しは、許可されていません。EJB 非同期メソッドのクライアント・プログラミング・モデル
Enterprise JavaBeans (EJB) 3.1 仕様に規定されているように、 ローカル・ビジネス、リモート・ビジネス、またはインターフェースなしのビューの 3 つのタイプのインターフェースを 介して、EJB 非同期メソッドを呼び出すことができます。EJB 2.1 クライアント・ビューまたは Web サービス・ビューを介した呼び出しは、許可されていません。


http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tejb_clientcode
ファイル名:tejb_clientcode.html