Java - how to get the stack trace from before a Runnable?

1.3k views Asked by At

I had a close look at the SO "questions that may already have your answer" here and surprised not to find what I'm asking for...

When an exception occurs in (for example) the EDT, or you just want to examine the stack for whatever reason, it's trivial to find the stack back to the run() of the Runnable. But how would you go about finding the thread (and hence stack) which ran the Runnable? and go about finding the thread (and hence stack) which ran that thread's Runnable... and so on and so on...

I'm aware of Thread.getAllStackTraces()... but how might one determine which of these threads called the "current thread"? Except "called" isn't the right word... I mean which ran the current thread.

2

There are 2 answers

6
K Erlandsson On BEST ANSWER

When you have started your new thread, the original thread has moved on to doing other stuff. Getting the stack trace of what that thread is doing at a later point in time is probably irrelevant. What you want is to capture the stack as it is when a thread is started.

What you could do is to create an Exception and pass to your Runnable when it is created. The exception will contain the stack up to when the runnable was created.

Something like this:

ExecutorService executor = Executors.newSingleThreadExecutor();

public void foo() {
    final Exception starterStackTrace = new Exception();
    executor.execute(new Runnable () {

        @Override
        public void run() {
            try {
                // do stuff
            } catch (Exception e) {
                e.printStackTrace(); // Thread exception
                starterStackTrace.printStackTrace(); // How thread was started
            }
        }
    });
}
0
mike rodent On

I asked this question 3 months ago now and I spent the summer, among other things, devising a whole load of tools connected with this... specifically for Jython exception-handling. Jythonistas will understand that there are things you can do in Jython which Java would struggle with massively.

Among other things I have managed to make these tools trace a sequence of Runnables (their stack recorded/frozen in time for future listing whenever you run a new Runnable) right back to the starter thread of an app.

Another challenge I faced was making all this work not just with running an app directly, but also when doing unit testing with the Python unittest module.

I'm surprised, in truth, that Jythonistas have (to my knowledge) never raised the problem of unittest in a Jython context, for the simple reason that if ever you need to start a new thread (typically to run something in the EDT) your failure results at the end of a unittest run may be unhelpful at best.

Anyone interested in checking out (maybe improving) my stuff is welcome to download it... pls drop me a line