!!! Asynchronous calls

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.

!!Example simple ServicePOJO
Take a look at [Echo.java|src/org/jboss/tutorial/asynch/bean/Echo.java] and [EchoRemote.java|src/org/jboss/tutorial/asynch/bean/EchoRemote.java]. They define a normal stateless session bean with a remote interface, nothing special. Now take a look at [Client.java|src/org/jboss/tutorial/asynch/client/Client.java]. 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(org.jboss.tutorial.asynch.bean.Echo.class.getName());
   System.out.println("-------- Synchronous call");
   String ret = echo.echo("normal call");
   System.out.println(ret);
}}}

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

{{{
   Echo asynchEcho = Asynch.getAsynchronousProxy(echo);
   System.out.println("-------- Asynchronous call");
   ret = asynchEcho.echo("asynchronous call");
   System.out.println("Direct return of async invocation is: " + ret);
}}}

As shown, you obtain the asynchronous proxy by calling {{org.jboss.ejb3.asynchronous.Asynch.getAsynchronousProxy()}} . 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");
   System.out.println(ret);
}}}

Now that we have finished everything we want to do while waiting for the asynchronus call to complete, we cast the asynchronus proxy to {{AsynchProvider}} and get hold of the {{Future}} contained.

{{{
      System.out.println("-------- Result of Asynchronous call");
      AsynchProvider provider = (AsynchProvider)asynchEcho;
      Future future = provider.getFuture();
}}}

Next we make sure that the asynchronus invocation has completed, and get the return value of the asynchronus invocation.
{{{
      System.out.println("Waiting for asynbch invocation to complete");
      while (!future.isDone())
      {
         Thread.sleep(100);
      }
      ret = (String)future.get();
      System.out.println(ret);
}}}


!!Building and running
To build and run the example, make sure you have ejb3.deployer installed in JBoss 4.0.x and have JBoss running. See the reference manual on how to install EJB 3.0.

{{{
Unix:    $ export JBOSS_HOME=<where your jboss 4.0 distribution is>
Windows: $ set JBOSS_HOME=<where your jboss 4.0 distribution is>
$ ant
$ ant run
Buildfile: build.xml

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] Waiting for asynbch invocation to complete
     [java] asynchronous call
}}}
