More and more we want to do asynchronous invocations. This allows us to get better performance because of concurrency, just take a look at the speed of AS 7.

 

But what happens when an asynchronous invocation fails. Most times the exception itself will tell us why it failed. But the real trouble might be in the caller code, not in the asynchronous task itself.

java.lang.Exception: throw up
    at org.jboss.beach.util.concurrent.SimpleExceptionTestCase$1.call(SimpleExceptionTestCase.java:49)
    at org.jboss.beach.util.concurrent.SimpleExceptionTestCase$1.call(SimpleExceptionTestCase.java:46)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:679)

The stack trace is in this case useless. Elvis has left the building, address unknown.

 

Then I spotted a gem in Remoting 3 by David M. Lloyd: glueing stacktraces. By glueing the stacktrace at the right moment we know where the call originated from. So I wrote up a MarkedExecutorService which can wrap any other ExecutorService to provide this functionality.

java.lang.Exception: throw up
    at org.jboss.beach.util.concurrent.SimpleExceptionTestCase$2.call(SimpleExceptionTestCase.java:68)
    at org.jboss.beach.util.concurrent.SimpleExceptionTestCase$2.call(SimpleExceptionTestCase.java:65)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:679)
    at ...asynchronous invocation...(Unknown Source)
    at org.jboss.beach.util.concurrent.SimpleExceptionTestCase.testMarkedException(SimpleExceptionTestCase.java:65)

 

Now we can easily see what instigated the throwing up. And thus cleaning up the mess can be done professionaly.

 

See https://github.com/wolfc/jboss-beach-executors for the source code of MarkedExecutorService.