JBoss.org Community Documentation

Chapter 36. Asynchronous proxy for EJBs - JBoss specific extension to EJB3

A JBoss extension to EJB 3.0 is that from the remote or local interface of a stateful session bean, stateless session bean or service bean you can obtain an asynchronous proxy. Methods called on the asynchronous proxy will be executed asynchronously, and the results can be obtained later on.


This JBoss specific feature of obtaining a asynchronous proxy to invoke any method on the bean asynchronously is NOT the same as the Asynchronous Methods feature in EJB 3.1. In EJB 3.1, you can mark your bean business methods to be asynchronous by using the @Asynchronous annotation.

Example :

Take a look at org.jboss.tutorial.asynch.bean.Echo and org.jboss.tutorial.asynch.bean.EchoBean. They define a normal stateless session bean with a remote interface, nothing special. Now take a look at org.jboss.tutorial.asynch.client.Client. It shows an example of asynchronous calls on a remote interface. We will walk through what it does here. The following lines just obtain the remote interface of the bean and call a method following the standard synchronous usage pattern:

InitialContext ctx = new InitialContext();
Echo echo = (Echo) ctx.lookup("EchoBean/remote");
System.out.println("-------- Synchronous call");
String ret = echo.echo("normal call");



Next we obtain the asynchronous proxy and make a call via that. The method will be invoked asynchronously :

Echo asynchEcho = org.jboss.ejb3.common.proxy.plugins.async.AsyncUtils.mixinAsync(echo);
System.out.println("-------- Asynchronous call");
ret = asynchEcho.echo("asynchronous call");
System.out.println("Direct return of async invocation is: " + ret);


We use the org.jboss.ejb3.common.proxy.plugins.async.AsyncUtils's mixinAsync method to create the asynchronous proxy. All methods invoked on this proxy are invoked asynchronously, and the returned value will always be null (or 0 in the case of numeric primitive types). In this example, the echo() method called has low overhead, but imagine if this was a method that took a long time. In this case it would be good to be able to go ahead with some other tasks.

In Client.java, we make another call on the normal remote interface while "waiting" for the asynchronous call:

System.out.println("-------- Synchronous call");
ret = echo.echo("normal call 2");

Now that we have finished everything we want to do, while waiting for the asynchronus call to complete, we invoke the getFutureResult(asynchProxy) API on the org.jboss.ejb3.common.proxy.plugins.async.AsyncUtils. This will return us an instance of java.util.concurrent.Future. To obtain the final result of the asynchronous call, we invoke the get() API on the returned java.util.concurrent.Future object.

System.out.println("-------- Result of Asynchronous call");
Future<String> future = (Future<String>) AsyncUtils.getFutureResult(asynchEcho);

// blocking call
ret = (String) future.get();



The java.util.concurrent.Future.get() API is blocking and if the asynchronous operation is not yet done, it will wait for the operation to complete.

Building and Running

From the command prompt, move to the "asynch" folder under the Section 1.3, “Set the EJB3_TUTORIAL_HOME”

Ant Users:

Make sure your JBossAS-5.x is running

$ ant
$ ant run

     [java] -------- Synchronous call
     [java] normal call
     [java] -------- Asynchronous call
     [java] Direct return of async invocation is: null
     [java] -------- Synchronous call
     [java] normal call 2
     [java] -------- Result of Asynchronous call
     [java] asynchronous call

Maven Users: Make sure the AS is not running.
$ mvn clean install -PRunSingleTutorial