You can extend SwingWorker to write the stack when it is created (or when executed, but then you need to create a different execution method, since it is final). Creating a reason is relatively expensive, although you may want to do this only when debugging (check the log level or some)
import java.util.concurrent.ExecutionException; import javax.swing.SwingWorker; public abstract class TracedSwingWorker<T, V> extends SwingWorker<T, V> { private final Exception cause; public TracedSwingWorker() { super(); this.cause = new Exception("TracedSwingWorker created at:"); } @Override protected final T doInBackground() throws Exception { try { return doWorkInBackground(); } catch(Exception e) { if(this.cause != null) { Throwable cause = e; while(cause.getCause() != null) { cause = cause.getCause(); } cause.initCause(this.cause); } throw e; } } protected abstract T doWorkInBackground();
prints:
java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Exception in SwingWorker! at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222) <snip> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662) Caused by: java.lang.Exception: SwingWorker created at: at TracedSwingWorker.<init>(TracedSwingWorker.java:15) at TracedSwingWorker$2.<init>(TracedSwingWorker.java:60) at TracedSwingWorker.main(TracedSwingWorker.java:60)
source share