Desarrollo de código cliente que llama a métodos asíncronos EJB
Puede utilizar el código de ejemplo de este tema para desarrollar código de cliente que llama a métodos asíncronos EJB.
Antes de empezar
public interface AcmeRemoteInterface {
void fireAndForgetMethod ();
Future<Integer> methodWithResults() throws AcmeException1, AcmeException2;
}
@Stateless
@Remote(AcmeRemoteInterface.class)
@Asynchronous
public class AcmeAsyncBean {
public void fireAndForgetMethod () {
// realizar trabajo no crítico
}
public Integer methodWithResults() {
Integer result;
// hacer el trabajo y, a continuación, devolver resultados
return result;
}
}
Acerca de esta tarea
Procedimiento
- Cree código de cliente que llame a un método asíncrono en el que no se devolverán resultados, a veces denominado método activar y olvidar.
Este tipo de método asíncrono no puede generar excepciones de la aplicación.
Sin embargo, pueden producirse excepciones del sistema que se deben resolver.
@EJB AcmeRemoteInterface myAsyncBean; try { myAsyncBean.fireAndForgetMethod(); } catch (EJBException ejbex) { // Método asíncrono nunca asignado, manejar error del sistema }
- Cree código de cliente que llame a un método asíncrono en el que se devuelven resultados.
- Cree código de cliente que llame a un método asíncrono en el que el cliente espera un máximo de 5 segundos (la hebra de cliente se bloquea durante este intervalo de tiempo) a recibir resultados. Los requisitos para el manejo de excepciones son los mismos que en el paso anterior. Por
ejemplo:
myResult = myFutureResult.get(5, TimeUnit.SECONDS);
- Cree código de cliente que llame a un método asíncrono en el que los resultados no se obtienen inmediatamente. Después de que se ejecute el método, el cliente recupera los resultados. Este esquema impide que la hebra de cliente se bloquee y el cliente queda libre para ejecutar otro trabajo mientras sondea los resultados. Los requisitos para el manejo de excepciones son los mismos que en los pasos anteriores. En este ejemplo, el cliente sondea periódicamente el objeto Future<V> para determinar cuándo ha finalizado la ejecución del método asíncrono. Por
ejemplo:
while (!myFutureResult.isDone()) { // Ejecute otro trabajo mientras espera a que finalice el método asíncrono. } // Se garantiza que esta llamada no se bloquea porque isDone ha devuelto true. myResult = myFutureResult.get();
- Cree código de cliente que llame a un método asíncrono en el que el cliente espera un máximo de 5 segundos (la hebra de cliente se bloquea durante este intervalo de tiempo) a recibir resultados. Los requisitos para el manejo de excepciones son los mismos que en el paso anterior. Por
ejemplo:
- Cree código de cliente para manejar excepciones de la aplicación. El código de cliente llama a un método asíncrono que devuelve una excepción de aplicación en el objeto Future<V>. En el ejemplo siguiente se muestra el código de manejo de excepciones necesario para determinar qué excepción de aplicación se ha producido.
@EJB AcmeRemoteInterface myAsyncBean; Future<Integer>>myFutureResult = null; Integer myResult = null; try { myFutureResult = myAsyncBean.methodWithResults(); } catch (EJBException ejbx) { // Método asíncrono nunca asignado, manejar excepción } // El método se asigna finalmente. Esperar resultados. try { myResult = myFutureResult.get(); } catch (ExecutionException ex) { // Determinar qué excepción de aplicación se ha producido durante la // llamada de método asíncrono. Throwable theCause = ex.getCause(); if (theCause instanceof AcmeException1) { // Manejar AcmeException1 } else if (theCause instanceof AcmeException2) { // Manejar AcmeException2 } else { // Manejar otras causas. } } catch ( ... ) { // Manejar otra excepción. }
- Cree código de cliente para identificar excepciones del sistema generadas por una llamada de método asíncrono durante la ejecución.
En el ejemplo siguiente se muestra el código de manejo de excepciones necesario para determinar si se ha producido una excepción del sistema.
@EJB AcmeRemoteInterface myAsyncBean; Future<Integer>>myFutureResult = null; Integer myResult = null; try { myFutureResult = myAsyncBean.methodWithResults(); } catch (EJBException ejbx) { // El método asíncrono no se ha asignado; manejar excepción. } // El método se asignará finalmente, bloquear ahora y esperar resultados try { myResult = myFutureResult.get(); } catch (ExecutionException ex) { // Buscar la clase de excepción que se ha producido durante el método asíncrono Throwable theCause = ex.getCause(); if (theCause instanceof EJBException) { // Manejar la EJBException que puede estar reiniciando una excepción del sistema // que se ha producido durante la ejecución del método asíncrono. Throwable theRootCause = theCause.getCause(); if (theRootCause != null) { // Manejar la excepción del sistema } } else ... // handle other causes } catch ( ... ) { // manejar otras excepciones }
- Opcionalmente, cree código de cliente para cancelar una llamada de método asíncrono. Si el intento resulta satisfactorio, entonces el método Future.isCancelled devuelve true y los métodos Future.get dan como resultado CancellationException. En el ejemplo siguiente se muestra el código necesario para cancelar una llamada de método asíncrono.
@EJB AcmeRemoteInterface myAsyncBean; Future<Integer> myFutureResult = myFutureResult.methodWithResults(); Integer myResult; if (myFutureResult.cancel(true)) { // El método asíncrono no se ha asignado. } else { // Ya se ha iniciado la ejecución del método asíncrono. El bean puede seguir // comprobando si se ha realizado un intento de cancelar la llamada. } if (myFutureResult.isCancelled()) { // La llamada de método asíncrona no ha empezado a ejecutarse porque el método // método cancel ha devuelto true en una línea anterior del ejemplo. } try { myResult = myFutureResult.get(); } catch (CancellationException ex) { // Manejar la excepción que se produce porque el método cancel ha devuelto // true en una línea anterior del ejemplo. }
- Opcionalmente, cree el código de bean para comprobar si un cliente ha intentado cancelar la llamada de método asíncrono.
En el ejemplo siguiente se muestra el código de bean necesario para comprobar si el cliente ha intentado cancelar la llamada de método asíncrono. Si el cliente ha intentado cancelar el trabajo, el método SessionContext.wasCancelCalled devuelve true y el código de bean puede evitar el trabajo innecesario.
@Resource SessionContext myContext; public Future<Integer> methodWithResults() { for (int i = 0; i < 3; i++) { // Realizar una parte del trabajo de larga ejecución. // Antes de continuar, compruebe si el cliente ha intentado cancelar este trabajo. if (myContext.wasCancelCalled()) { throw new AcmeCancelCalledException(); } } // ... }
- Devuelva valores de varias salidas de la invocación de método asíncrono.
En algunos casos, un método debe devolver varios datos.
Una forma de realizar esta tarea es utilizando la semántica de pase por referencia. En este enfoque, se pasa un objeto al método como un parámetro, actualizado por el método y, a continuación, el valor actualizado está disponible para el cliente. Este enfoque funciona para los métodos asíncronos, pero no es el modelo óptimo.
Para devolver varios datos, cree un derivador dentro del objeto Future que sea devuelto por el método. En este enfoque, se define un objeto derivador que contiene las variables de instancia que contienen los diferentes datos que se deben devolver. El método asíncrono establece estos datos en el objeto derivador y los devuelve y el código de cliente recupera luego estos datos del objeto Future.
Incluir varios datos dentro del objeto derivador es un patrón local o remoto transparente que identifica exactamente cuándo se dispone de los resultados. En cambio, la técnica de pase por referencia tradicional no ofrece al cliente una forma fácil de determinar cuándo se dispone de los resultados. El objeto que se pasa no se actualiza hasta que se ejecuta el método asíncrono y el cliente no puede determinar cuándo se ha producido esto de ninguna otra forma que interrogando al objeto Future utilizando los métodos Future.isDone() o Future.get().
// Este es el objeto resultante que se devuelve del método asíncrono. // Este objeto se envuelve en un objeto Future, y contiene los dos datos // que se deben devolver del método. class ResultObject { public Boolean myResult; pubilc String myInfo; }
// Este es el código de método asíncrono que obtiene los resultados y los devuelve. @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); }
// Este es el código de cliente que obtiene ResultObject y luego extrae los datos necesarios de éste. Future<ResultObject> myFutureResult = myBeanRef.asyncMethod1(someInputData); ResultObject theResult = myFutureResult.get(); boolean didItWork = theResult.myResult; String explanation = theResult.myInfo;
Subtopics
Modelo de programación de cliente para métodos asíncronos EJB
Tal como se describe en la especificación de Enterprise JavaBeans (EJB) 3.1, puede invocar los métodos asíncronos EJB a través de los siguientes tipos de interfaz: de empresa local, de empresa remota o de vista sin interfaz. No se permiten invocaciones mediante una vista de cliente EJB 2.1 o una vista de servicios web.Modelo de programación de cliente para métodos asíncronos EJB
Tal como se describe en la especificación de Enterprise JavaBeans (EJB) 3.1, puede invocar los métodos asíncronos EJB a través de los siguientes tipos de interfaz: de empresa local, de empresa remota o de vista sin interfaz. No se permiten invocaciones mediante una vista de cliente EJB 2.1 o una vista de servicios web.


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