Clientcode für das Aufrufen asynchroner EJB-Methoden entwickeln
Sie können den Beispielcode in diesem Artikel verwenden, um Clientcode zu entwickeln, der asynchrone EJB-Methoden aufruft.
Vorbereitende Schritte
public interface AcmeRemoteInterface {
void fireAndForgetMethod ();
Future<Integer> methodWithResults() throws AcmeException1, AcmeException2;
}
@Stateless
@Remote(AcmeRemoteInterface.class)
@Asynchronous
public class AcmeAsyncBean {
public void fireAndForgetMethod () {
// Nicht kritische Arbeiten ausführen.
}
public Integer methodWithResults() {
Integer result;
// Arbeiten ausführen und Ergebnisse zurückgeben.
return result;
}
}
Informationen zu diesem Vorgang
Vorgehensweise
- Clientcode erstellen, der eine asynchrone Methode aufruft, die keine Ergebnisse zurückgibt und manchmal auch
als Fire and Forget-Methode bezeichnet wird.
Dieser Typ einer asynchronen Methode kann zu Ausnahmen in der Anwendung führen.
Es können jedoch Systemausnahmen eintreten, die behoben werden müssen.
@EJB AcmeRemoteInterface myAsyncBean; try { myAsyncBean.fireAndForgetMethod(); } catch (EJBException ejbex) { // Asynchrone Methode wird nicht zugeteilt, Systemfehler behandeln. }
- Clientcode erstellen, der eine asynchrone Methode aufruft, die Ergebnisse zurückgibt.
- Erstellen Sie Clientcode, der eine asynchrone Methode aufruft, bei der der Client bis zu 5 Sekunden
auf den Empfang der Ergebnisse wartet (der Clientthread ist in diesem Zeitfenster blockiert).
Für die Ausnahmebehandlung gelten dieselben Voraussetzungen wie im vorherigen Schritt.
Beispiel:
myResult = myFutureResult.get(5, TimeUnit.SECONDS);
- Erstellen Sie Clientcode, der eine asynchrone Methode aufruft, bei der die Ergebnisse nicht sofort
abgerufen werden.
Nach der Ausführung der Methode ruft der Client die Ergebnisse ab.
Dieses Schema verhindert eine Blockierung des Clienthreads, und der Client ist für die
Ausführung anderer Arbeiten frei, während die Ergebnisse abgerufen werden.
Für die Ausnahmebehandlung gelten dieselben Voraussetzungen wie in den vorherigen Schritten.
In diesem Beispiel fragt der Client das Future<V>-Objekt in regelmäßigen Abständen ab, um festzustellen,
ob die Ausführung der asynchronen Methode abgeschlossen ist.
Beispiel:
while (!myFutureResult.isDone()) { // Beim Warten auf den Abschluss asynchroner Methoden andere Arbeiten ausführen. } // Dieser Aufruf wird garantiert nicht blockiert, weil isDone "true" zurückgegeben hat. myResult = myFutureResult.get();
- Erstellen Sie Clientcode, der eine asynchrone Methode aufruft, bei der der Client bis zu 5 Sekunden
auf den Empfang der Ergebnisse wartet (der Clientthread ist in diesem Zeitfenster blockiert).
Für die Ausnahmebehandlung gelten dieselben Voraussetzungen wie im vorherigen Schritt.
Beispiel:
- Clientcode für die Behandlung von Anwendungsausnahmen erstellen. Der Clientcode ruft eine asynchrone
Methode auf, die eine Anwendungsausnahme im Future<V>-Objekt zurückgibt.
Das folgende Beispiel veranschaulicht den Ausnahmebehandlungscode, der erforderlich ist, um die eingetretene
Anwendungsausnahme zu bestimmen.
@EJB AcmeRemoteInterface myAsyncBean; Future<Integer>>myFutureResult = null; Integer myResult = null; try { myFutureResult = myAsyncBean.methodWithResults(); } catch (EJBException ejbx) { // Asynchrone Methode wird nicht zugeteilt, Ausnahme behandeln. } // Methode wird letztendlich zugeteilt. Auf Ergebnisse warten. try { myResult = myFutureResult.get(); } catch (ExecutionException ex) { // Die während des asynchronen Methodenaufrufs eingetretene // Anwendungsausnahme bestimmen. Throwable theCause = ex.getCause(); if (theCause instanceof AcmeException1) { // AcmeException1 behandeln. } else if (theCause instanceof AcmeException2) { // AcmeException2 behandeln. } else { // Weitere Ursachen behandeln. } } catch ( ... ) { // Weitere Ausnahmen behandeln. }
- Clientcode erstellen, der Systemausnahmen identifiziert, die während der
Ausführung vom asynchronen Methodenaufruf ausgelöst werden.
Das folgende Beispiel veranschaulicht den Ausnahmebehandlungscode, der erforderlich ist, um zu bestimmen,
ob eine Systemausnahme eingetreten ist.
@EJB AcmeRemoteInterface myAsyncBean; Future<Integer>>myFutureResult = null; Integer myResult = null; try { myFutureResult = myAsyncBean.methodWithResults(); } catch (EJBException ejbx) { // Asynchrone Methode wurde nicht zugeteilt, Ausnahme behandeln. } // Methode wird letztendlich zugeteilt; deshalb blockieren und auf Ergebnisse warten. try { myResult = myFutureResult.get(); } catch (ExecutionException ex) { // Ausnahmeklasse suchen, die während der asynchronen Methode ausgegeben wurde. Throwable theCause = ex.getCause(); if (theCause instanceof EJBException) { // EJBException behandeln, die eine Systemausnahme enthalten kann, // die während der Ausführung der asynchronen Methode eingetreten ist. Throwable theRootCause = theCause.getCause(); if (theRootCause != null) { // Systemausnahme behandeln. } } else ... // Weitere Ursachen behandeln. } catch ( ... ) { // Weitere Ausnahmen behandeln. }
- (Optional) Clientcode erstellen, der einen asynchronen
Methodenaufruf abbricht. Wenn dieser Versuch erfolgreich ist, gibt die Methode
"Future.isCancelled" den Wert "true" zurück, und die Methoden "Future.get" führt zu einer
Ausnahme des Typs "CancellationException". Das folgende Beispiel veranschaulicht den Code, der erforderlich ist,
um einen asynchronen Methodenaufruf abzubrechen.
@EJB AcmeRemoteInterface myAsyncBean; Future<Integer> myFutureResult = myFutureResult.methodWithResults(); Integer myResult; if (myFutureResult.cancel(true)) { // Asynchrone Methode wurde nicht zugeteilt. } else { // Ausführung der asynchronen Methode wurde bereits gestartet. Die Bean kann trotzdem // prüfen, ob versucht wurde, den Aufruf abzubrechen. } if (myFutureResult.isCancelled()) { // Ausführung des asynchronen Methodenaufrufs wurde nicht gestartet, weil // die Methode cancel in der vorherigen Zeile des Beispiels true zurückgegeben hat. } try { myResult = myFutureResult.get(); } catch (CancellationException ex) { // Ausnahme behandeln, die eintritt, weil die Methode cancel in einer // vorherigen Zeile des Beispiels true zurückgegeben hat. }
- (Optional) Beancode erstellen, der prüft, ob ein Client versucht hat,
den asynchronen Methodenaufruf abzubrechen.
Das folgende Beispiel veranschaulicht den Beancode, der erforderlich ist, um zu prüfen, ob der Client
versucht hat, den asynchronen Methodenaufruf abzubrechen.
Wenn der Client versucht hat, den Aufruf abzubrechen, gibt die Methode "SessionContext.wasCancelCalled"
den Wert "true" zurück, und der Beancode kann unnötige Arbeiten vermeiden.
@Resource SessionContext myContext; public Future<Integer> methodWithResults() { for (int i = 0; i < 3; i++) { // Einen Teil einer Arbeit mit langer Laufzeit ausführen. // Vor der Fortsetzung prüfen, ob der Client versucht hat, die Arbeit abzubrechen. if (myContext.wasCancelCalled()) { throw new AcmeCancelCalledException(); } } // ... }
- Mehrere Ausgabewerte über den asynchronen Methodenaufruf zurückgeben.
Manchmal muss eine Methode mehrere Datenabschnitte zurückgeben.
Eine Methode zur Bewältigung dieser Aufgabe ist die Verwendung der Semantik "Nach Referenz übergeben". Bei diesem Ansatz wird ein Objekt in der Methode als Parameter übergeben, von der Methode aktualisiert, und anschließend steht der aktualisierte Wert dem Client zur Verfügung. Dieser Ansatz funktioniert für asynchrone Methode, ist aber nicht das optimale Muster.
Wenn mehrere Datenabschnitte zurückgegeben werden sollen, erstellen Sie einen Wrapper im Future-Objekt, das von der Methode zurückgegeben wird. Bei diesem Ansatz wird ein Wrapperobjekt definiert, das Instanzvariablen enthält, die die Datenabschnitte enthält, die zurückgegeben werden müssen. Die asynchrone Methode definiert die Datenabschnitte im Wrapperobjekt und gibt es zurück, und der Clientcode ruft diese Daten anschließend aus dem Future-Objekt ab.
Das Einbetten mehrerer Datenabschnitte in das Wrapperobjekt ist ein lokales oder fernes transparentes Muster, das exakt identifiziert, wann die Ergebnisse verfügbar sind. Hingegen kann der Client mit der traditionellen Technik "Nach Referenz übergeben" (pass-by-reference) nicht so einfach bestimmen, wann die Ergebnisse verfügbar sind. Das übergebene Objekt wird erst aktualisiert, wenn die asynchrone Methode ausgeführt wird, und der Client kann nur durch Abfrage des Future-Objekts mimt den Methoden Future.isDone() und Future.get() bestimmen, wann dieser Fall eingetreten ist.
// Ergebnisobjekt, das von der asynchronen Methode zurückgegeben wird. // Dieses Objekt wird in ein Future-Objekt gepackt und enthält die beiden // Datenabschnitte, die von der Methode zurückgegeben werden müssen. class ResultObject { public Boolean myResult; pubilc String myInfo; }
// Asynchroner Methodencode, der die Ergebnisse abruft und zurückgibt. @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); }
// Clientcode, der das ResultObject abruft und anschließend die // erforderlichen Daten aus diesem Objekt extrahiert. Future<ResultObject> myFutureResult = myBeanRef.asyncMethod1(someInputData); ResultObject theResult = myFutureResult.get(); boolean didItWork = theResult.myResult; String explanation = theResult.myInfo;
Unterartikel
Clientprogrammiermodell für asynchrone EJB-Methoden
Wie in der Spezifikation Enterprise JavaBeans (EJB) 3.1 dokumentiert, können Sie asynchrone EJB-Methoden über lokale Geschäftsschnittstellen, ferne Geschäftsschnittstellen oder eine Sicht ohne Schnittstellen aufrufen. Aufrufe über eine EJB-2.1-Clientsicht oder eine Web-Service-Sicht sind nicht zulässig.Clientprogrammiermodell für asynchrone EJB-Methoden
Wie in der Spezifikation Enterprise JavaBeans (EJB) 3.1 dokumentiert, können Sie asynchrone EJB-Methoden über lokale Geschäftsschnittstellen, ferne Geschäftsschnittstellen oder eine Sicht ohne Schnittstellen aufrufen. Aufrufe über eine EJB-2.1-Clientsicht oder eine Web-Service-Sicht sind nicht zulässig.


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