Desenvolvendo Código do Cliente que Chama os Métodos Assíncronos do EJB
É possível usar o código de amostra neste tópico para desenvolver código do cliente que chama os métodos assíncronos do EJB.
Antes de Iniciar
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;
}
}
Sobre Esta Tarefa
Procedimento
- Crie um código do cliente que chama um método assíncrono em que nenhum
resultado é retornado, às vezes chamado de método fire and forget.
Esse tipo de método assíncrono não pode resultar em exceções do aplicativo.
Entretanto, exceções do sistema podem ocorrer, devendo ser resolvidos.
@EJB AcmeRemoteInterface myAsyncBean; try { myAsyncBean.fireAndForgetMethod(); } catch (EJBException ejbex) { // O método assíncrono nunca despachou, erro do sistema de manipulação }
- Crie um código do cliente que chama um método assíncrono em que
resultados são retornados.
- Crie o código do cliente que chama um método assíncrono em que o
cliente aguarda até 5 segundos (o encadeamento do cliente é bloqueado durante
esse espaço de tempo) para receber resultados. Os requisitos de manipulação de exceção
são os mesmos que na etapa anterior. Por exemplo:
myResult = myFutureResult.get(5, TimeUnit.SECONDS);
- Crie um código do cliente que chama um método assíncrono em que
os resultados não são obtidos imediatamente. Depois que o método for executado, o cliente
receberá os resultados. Esse esquema impede que o encadeamento do cliente
seja bloqueado e o cliente poderá executar normalmente outro trabalho enquanto
pesquisa os resultados. Os requisitos de manipulação de exceção
são os mesmos que nas etapas anteriores. Nesse exemplo, o cliente pesquisa periodicamente o
objeto Future<V> para determinar quando a execução do método assíncrono foi concluído. Por exemplo:
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();
- Crie o código do cliente que chama um método assíncrono em que o
cliente aguarda até 5 segundos (o encadeamento do cliente é bloqueado durante
esse espaço de tempo) para receber resultados. Os requisitos de manipulação de exceção
são os mesmos que na etapa anterior. Por exemplo:
- Crie o código do cliente para manipular exceções do aplicativo. O código do cliente chama um método assíncrono que
retorna uma exceção do aplicativo no objeto Future<V>. O seguinte exemplo demonstra o código de manipulação de exceção necessário
para determinar qual exceção do aplicativo ocorreu.
@EJB AcmeRemoteInterface myAsyncBean; Future<Integer>>myFutureResult = null; Integer myResult = null; try { myFutureResult = myAsyncBean.methodWithResults(); } catch (EJBException ejbx) { // O método assíncrono nunca despachou, exceção de manipulação } // O método é eventualmente despachado. Aguarde os resultados. try { myResult = myFutureResult.get(); } catch (ExecutionException ex) { // Determine que exceção de aplicativo ocorreu durante a // chamada do método assíncrono. Throwable theCause = ex.getCause(); if (theCause instanceof AcmeException1) { // Manipular AcmeException1 } else if (theCause instanceof AcmeException2) { // Manipular AcmeException2 } else { // Manipular outras causas. } } catch ( ... ) { // Manipular outra exceção. }
- Crie o código do cliente para identificar as exceções do sistema emitidas
pela chamada do método assíncrono durante a execução.
O seguinte exemplo demonstra o código de manipulação de exceção necessário
para determinar se ocorreu uma exceção do sistema.
@EJB AcmeRemoteInterface myAsyncBean; Future<Integer>>myFutureResult = null; Integer myResult = null; try { myFutureResult = myAsyncBean.methodWithResults(); } catch (EJBException ejbx) { // O método assíncrono não foi despachado; exceção de manipulação. } // Method will eventually be dispatched so block now and wait for results try { myResult = myFutureResult.get(); } catch (ExecutionException ex) { // Localize a classe de exceção que ocorreu durante o método assíncrono Throwable theCause = ex.getCause(); if (theCause instanceof EJBException) { // Manipule o EJBException que pode estar agrupando uma exceção do sistema // ocorrida durante a execução do método assíncrono. Throwable theRootCause = theCause.getCause(); if (theRootCause != null) { // Manipule a exceção do sistema } } else ... // handle other causes } catch ( ... ) { // manipule outras exceções }
- Opcionalmente, crie um código do cliente para cancelar uma chamada de
método assíncrono. Se essa tentativa obtiver êxito, o método Future.isCancelled
retornará true e os métodos Future.get resultarão na CancellationException. O seguinte exemplo demonstra o código necessário para cancelar uma chamada de
método assíncrono.
@EJB AcmeRemoteInterface myAsyncBean; Future<Integer> myFutureResult = myFutureResult.methodWithResults(); Integer myResult; if (myFutureResult.cancel(true)) { // O método assíncrono não foi despachado. } else { // O método assíncrono já iniciou a execução. O bean ainda pode verificar // se foi feita uma tentativa de cancelar a chamada. } if (myFutureResult.isCancelled()) { // A chamada do método assíncrono não iniciou a execução porque o método de // cancelamento retornou true em uma linha anterior do exemplo. } try { myResult = myFutureResult.get(); } catch (CancellationException ex) { // Manipule a exceção que ocorre, porque o método de cancelamento retornou true // em uma linha anterior do exemplo. }
- Opcionalmente, crie um código de bean para verificar se um cliente tentou cancelar
a chamada de método assíncrono.
O seguinte exemplo demonstra o código de bean necessário para verificar se o cliente tentou cancelar a chamada de
método assíncrono. Se o cliente tentou cancelar o trabalho, o método SessionContext.wasCancelCalled
retornará true e o código de bean poderá evitar um trabalho desnecessário.
@Resource SessionContext myContext; public Future<Integer> methodWithResults() { for (int i = 0; i < 3; i++) { // Execute uma parte do trabalho de execução longa. // Antes de continuar, verifique se o cliente tentou cancelar esse trabalho. if (myContext.wasCancelCalled()) { throw new AcmeCancelCalledException(); } } // ... }
- Passe novamente vários valores de saída a partir da chamada de método
assíncrono.
Em alguns casos, um método deve passar novamente várias partes de dados.
Uma forma de executar essa tarefa é usando as semânticas passar por referência. Nessa abordagem, um objeto é passado para o método como um parâmetro, atualizado pelo método e, em seguida, o valor atualizado fica disponível para o cliente. Essa abordagem funciona para métodos assíncronos, mas não é o padrão ideal.
Para retornar várias partes de dados, crie um wrapper dentro do objeto Future que é retornado pelo método. Nessa abordagem, um objeto wrapper é definido contendo variáveis de instância que mantêm partes diferentes de dados que devem ser retornados. O método assíncrono configura essas partes de dados no objeto wrapper e as retorna e o código do cliente, então, recupera esses dados do objeto Future.
Integrar várias partes de dados no objeto wrapper é um padrão transparente local ou remoto, que identifica exatamente quando os resultados estão disponíveis. Em contraste, a técnica passar por referência tradicional não fornece ao cliente uma maneira fácil para determinar quando os resultados estão disponíveis. O objeto passado não é atualizado enquanto o método assíncrono não ser executado e o cliente não pode determinar quando isso ocorreu, ao contrário de interrogar o objeto Future usando os métodos Future.isDone() ou 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;
Subtópicos
Modelo de Programação de Cliente para Métodos Assíncronos EJB
Conforme documentado na especificação Enterprise JavaBeans (EJB) 3.1, é possível chamar métodos assíncronos EJB por meio dos seguintes tipos de interface: negócios locais, negócios remotos ou visualização sem interface. As chamadas feitas por meio de uma visualização do cliente EJB 2.1, ou de uma visualização de serviços da Web, não são permitidas.Modelo de Programação de Cliente para Métodos Assíncronos EJB
Conforme documentado na especificação Enterprise JavaBeans (EJB) 3.1, é possível chamar métodos assíncronos EJB por meio dos seguintes tipos de interface: negócios locais, negócios remotos ou visualização sem interface. As chamadas feitas por meio de uma visualização do cliente EJB 2.1, ou de uma visualização de serviços da Web, não são permitidas.


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