I have a stateless EJB-3.1 session bean containing an asynchronous method that does some expensive processing and returns a future to the client, thereby allowing it to display the processing result once it’s ready:
@Asynchronous
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public Future<String> importModules() {
String result = doSomeHeavyStuff();
return new AsyncResult<String>(result);
}
This bean is running on a JBoss 6 instance and invoked remotely from a Swing client:
final Future<String> termination =
Proxy.getProxy().getMenfpImportService().importModules();
SwingWorker<String, Object> worker = new SwingWorker<String, Object>() {
@Override
protected String doInBackground() {
/* ... */
if (termination.isDone()) {
return termination.get();
}
/* ... */
}
/* ... */
}
While the processing usually finishes successfully, some computations take longer than 300 seconds to finish.
For these computations, a JBoss socket timeout causes the client to receive an ExecutionException instead of the computation result when calling termination.get():
10:26:16,301 INFO Application:1150 - Execution exception during modules import:
java.util.concurrent.ExecutionException: org.jboss.remoting.InvocationFailureException: Socket timed out. Waited 300000 milliseconds for response while calling on InvokerLocator [socket://degotte:3873/?timeout=300000]; nested exception is:
java.net.SocketTimeoutException: Read timed out
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
at java.util.concurrent.FutureTask.get(FutureTask.java:83)
at org.jboss.ejb3.async.spi.AsynchronousClientFuture.get(AsynchronousClientFuture.java:113)
at org.jboss.ejb3.async.impl.util.concurrent.LocalJvmSerializableFutureWrapper.get(LocalJvmSerializableFutureWrapper.java:161)
at lu.lippmann.forminitiale.client.gui.Application$2.doInBackground(Application.java:1137)
at lu.lippmann.forminitiale.client.gui.Application$2.doInBackground(Application.java:1)
at javax.swing.SwingWorker$1.call(SwingWorker.java:277)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at javax.swing.SwingWorker.run(SwingWorker.java:316)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Unfortunately, the @Asynchronous annotation doesn’t provide any configuration options.
My question is how I can increase the client server communication socket timeout, and if in any way possible only for the connection established during the invocation of the asynchronous method.
Thanks,
Thomas
The link posted by Nayan Wadekar pointed to the right direction. The component responsible for managing the sockets on a JBoss AS is JBoss remoting which provides so-called Connectors to call the suitable invocation handlers for the connecting transports.
In the case of an EJB method invocation the responsible connector seems to be the DefaultEjb3Connector whose parameters can be configured in the file ejb3-connectors-jboss-beans.xml in the deploy folder, e.g. in
if using the default profile.
Raising the timeout parameter after the socket URL proved to be effective.
However, this raises the timeout for all EJB method invocations. Given what I have read about the concepts of JBoss remoting, I am not sure whether adding an adapted connector for certain session beans only is actually possible.