assuming I have the code like as below:
Future
The ForkJoinPool
creates ForkJoinTask
instances to execute your submissions.
ForkJoinTask
tries to provide an accurate stack trace when exceptions occur. Its javadoc states
Rethrown exceptions behave in the same way as regular exceptions, but, when possible, contain stack traces (as displayed for example using
ex.printStackTrace()
) of both the thread that initiated the computation as well as the thread actually encountering the exception; minimally only the latter.
This is the comment in the private implementation of this behavior
/** * Returns a rethrowable exception for the given task, if * available. To provide accurate stack traces, if the exception * was not thrown by the current thread, we try to create a new * exception of the same type as the one thrown, but with the * recorded exception as its cause. If there is no such * constructor, we instead try to use a no-arg constructor, * followed by initCause, to the same effect. If none of these * apply, or any fail due to other exceptions, we return the * recorded exception, which is still correct, although it may * contain a misleading stack trace. * * @return the exception, or null if none */ private Throwable getThrowableException() {
In other words, it takes the IllegalStateException
your code threw, finds a constructor of IllegalStateException
that receives a Throwable
, invokes that constructor with the original IllegalStateException
as its argument, and returns the result (which is then rethrown within a ExecutionException
).
Your stack trace now also contains the stack trace for the get
call.
With ForkJoinPool
as your ExecutorService
, I don't believe you can avoid it, it's dependent on if the exception was not thrown by the current thread and the constructors available in the thrown exception type.