Skip to content
Advertisement

Preserve Java stack trace across threads

I am using ExecutorService to send mails asynchronously, so there is a class:

JavaScript

That handles the sending. Any exception that gets caught is logged, for (anonymized) example:

JavaScript

Not very helpful – I need to see the stacktrace that invoked the ExecutorService that caused all of this. My solution is to create an empty Exception and pass it into Mailer:

JavaScript

And now in the case of exception I want to log the problem itself and its cause from the other thread:

JavaScript

This works great but produces two logs. I want to combine t and cause into a single exception and log that one. In my opinion, t caused cause, so using cause.initCause(t) should be the right way. And works. I see a full stack trace: from where the call originated all the way up to the AddressException.

Problem is, initCause() works only once and then crashes. Question 1: can I clone Exception? I’d clone cause and init it with t every time.

I tried t.initCause(cause), but that crashes right away.

Question 2: is there another smart way to combine these 2 exceptions? Or just keep one thread context in the other thread context for logging purposes?

Advertisement

Answer

Following my comment, this is actually what I had in mind. Mind you, I don’t have a way to test it at the moment.

What you pass from your parent thread is New Exception().getStackTrace(). Or better yet, as @Radiodef commented, Thread.currentThread().getStackTrace(). So it’s basically a StackTraceElement[] array.

Now, you can have something like:

JavaScript

Now in your catch clause you can do something like:

JavaScript

Which will give you a boundary between the two stack traces.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement