3/17/2010

Simple Asynchronous methods in EJB 3.1

EJB 3.1 introduced a simple mechanism for asynchronous invocation. This post presents such an example with a Singleton session bean and its JUnit test case. 2 styles of asynchronous EJB invocations are used:

(1) fire-and-forget asynchronous methods having void return type.

(2) retrieve-result-later asynchronous methods having Future<?> return type.

package test;

import java.util.concurrent.Future;
import javax.ejb.Asynchronous;
import javax.ejb.AsyncResult;
import javax.ejb.Singleton;

@Singleton
@Asynchronous
public class AsyncBean {
@Asynchronous //this line can be omitted
public void ignoreResult(int a, int b) {
// the client doesn't care what happens here
}

@Asynchronous //this line can be omitted
public Future<Integer> longProcessing(int a, int b) {
return new AsyncResult<Integer>(a * b);
}
}
Since the class is annotated with @Asynchronous, all business methods are asynchronous. The method-level @Asynchronous is therefore redundant, and kept there for illustration purpose.
package test;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.ejb.embeddable.EJBContainer;
import javax.naming.Context;
import junit.framework.TestCase;

public class AsyncBeanTest extends TestCase {
private EJBContainer container;
private Context namingContext;
private AsyncBean asyncBean;

@Override
protected void setUp() throws Exception {
super.setUp();
container = EJBContainer.createEJBContainer();
namingContext = container.getContext();
asyncBean = (AsyncBean) namingContext.lookup("java:global/testApp/AsyncBean");
}

@Override
protected void tearDown() throws Exception {
super.tearDown();
container.close();
}

public final void testIgnoreResult() {
asyncBean.ignoreResult(0, 0); // fire and forget
System.out.println("Proceed without waiting for the async method result.");
}

public final void testLongProcessing() throws InterruptedException, ExecutionException {
Future<Integer> futureResult = asyncBean.longProcessing(8, 9);
System.out.println("Proceed to other tasks and check async method result later.");
Integer intResult = futureResult.get();
System.out.println("The prior async method returned " + intResult);
}
}
I've tested this example with GlassFish V3 in its embedded mode. It should work with any Java EE 6 application servers as well. The configureation (classpath, outputDir, etc) and how to run it are the same as EJB Lite testing with JUnit and embeddable container.

2 comments:

Steve Smith said...

Great and Useful Article.

Online Java Training

Java Online Training India

Java Online Course

Java EE course

Java EE training

Best Recommended books for Spring framework

Java Interview Questions








Java Course in Chennai

Java Online Training India

Vũ Diệu Linh said...

I enjoyed on reading your blog post. Very interesting to read this article.I would like to thank you for the efforts you had made for writing this awesome article. Please visit my website, Friv 4000 Games is where all the free friv games.
Friv 4000