Here's an unusual one: is it possible to obtain the class/method that originally spawned the currently running thread? Running a stack trace will naturally stop at the top of the call stack for the current thread.
-
1I hope you're doing this for some hacky debugging and not anything important. – Mark Peters Jun 15 '11 at 21:52
-
Haha, you assume correctly. I haven't stopped holding my nose since I started down this path :-D – Wilco Jun 15 '11 at 21:59
-
Related (but not identical): [Forging a stack trace in Java](http://stackoverflow.com/questions/6270256/forging-a-stack-trace-in-java) – Paŭlo Ebermann Jun 15 '11 at 22:02
-
@Mark, it can be used for security reasons, although I am sure it is not. – bestsss Jun 16 '11 at 06:27
4 Answers
Yes, you can: I offer you 2 ways: one standard and one semi-hack.
Most of the answers go overboard while it's supposed to be built-in function in Java.
Install a security manager and override SecurityManager.getThreadGroup()
, you can get the stack trace easily, optionally you can disable the rest of the secutiry checks by overriding the rest of the methods too.
Hacky one: install an InheritableThreadLocal in the main thread (the one named main and run by method main(String[] args)). Override the protected InheritableThreadLocal.childValue(T parentValue)
and you are done.
Note: you get the stacktrace of the thread being created and the parent thread (reference) but that should be enough to trace issues.
I decided to write the super simple sample to illustrate how easy it is: Here you can see the results. Looking at the sample, I guess that the most elegant solution I have ever posted on this site, mostly b/c it's non-obvious but simple and smart.
package bestsss.util;
import java.util.Arrays;
public class StackInterceptor extends InheritableThreadLocal<StackTraceElement[]>{
public static final StackInterceptor instance;
static{
instance = new StackInterceptor();
instance.set(new Throwable().getStackTrace());
}
@Override
protected StackTraceElement[] childValue(StackTraceElement[] parentValue) {
return new Throwable().getStackTrace();
}
//test//
public static void main(String[] args) {
Runnable r= new Runnable(){
@Override
public void run() {
System.out.printf("%s - creation stack: %s%n", Thread.currentThread(), Arrays.toString(instance.get()).replace(',', '\n'));
}
};
Thread t1 = new Thread(r, "t1");
//spacer
Thread t2 = new Thread(r, "t2");
t1.start();
t2.start();
}
}
Thread[t1,5,main] - creation stack: [bestsss.util.StackInterceptor.childValue(StackInterceptor.java:13) bestsss.util.StackInterceptor.childValue(StackInterceptor.java:1) java.lang.ThreadLocal$ThreadLocalMap.(ThreadLocal.java:334) java.lang.ThreadLocal$ThreadLocalMap.(ThreadLocal.java:242) java.lang.ThreadLocal.createInheritedMap(ThreadLocal.java:217) java.lang.Thread.init(Thread.java:362) java.lang.Thread.(Thread.java:488) bestsss.util.StackInterceptor.main(StackInterceptor.java:25)] Thread[t2,5,main] - creation stack: [bestsss.util.StackInterceptor.childValue(StackInterceptor.java:13) bestsss.util.StackInterceptor.childValue(StackInterceptor.java:1) java.lang.ThreadLocal$ThreadLocalMap.(ThreadLocal.java:334) java.lang.ThreadLocal$ThreadLocalMap.(ThreadLocal.java:242) java.lang.ThreadLocal.createInheritedMap(ThreadLocal.java:217) java.lang.Thread.init(Thread.java:362) java.lang.Thread.(Thread.java:488) bestsss.util.StackInterceptor.main(StackInterceptor.java:27)]
Good luck and happy hacking.

- 11,796
- 3
- 53
- 63
-
A solution with InheritableThreadLocal is a beautiful one. I'm wondering if it's possible to use it if the source of main() is not available (e.g. in a case of application server) – Oleg Pavliv Sep 21 '11 at 07:00
-
it is of course, `main()` is the first (usually, erm almost) method to be called in the application. If it's unavailable, after initializing the threadLocal all child (and grand-child++) threads spawned will be traceable. In short do the init part as soon as you can. – bestsss Sep 21 '11 at 08:05
Normally, no.
If you can control your thread creation, you could subclass Thread and register the stack trace in the constructor. Of course, this is then the method which created the thread, not necessarily the one which called .start()
. Thus better override this method.
But often you would use Thread pools instead, where you would like to know which method submitted the task to the executor's execute()
, not which method started the thread.

- 73,284
- 20
- 146
- 210
-
If you control the pool, there is nothing much to wonder, you do control even the threadFactory, so it was the thread factory. – bestsss Jun 16 '11 at 06:52
-
@bestsss: Yes. My point was that this thread factory method would normally not be what you really **want to know** - you would want to know who (which method) submitted the work to the thread pool (or who created the runnable object). For this, your thread pool would have to add metadata to all the tasks, and somehow provide a means to retrieve this. – Paŭlo Ebermann Jun 16 '11 at 12:18
-
1ŭlo, you have `newTaskFor(...)` in `AbstractExecutorService` to decorate tasks. On the contrary knowing when the 1st task spawned a thread could be quite important. While not obvious why, the newly created thread inherits quite a bit from the parent and it takes a diligent ThreadFactory to prevent leaks (ClassLoader, AccessControlContext, ThreadGroup, etc) – bestsss Jun 16 '11 at 12:23
-
Good idea with the `newTaskFor` ... but the default thread pools (ThreadPoolExecutor) don't store any metadata about the calling thread there, do they? I didn't think of the implications of the thread leakage, good point. – Paŭlo Ebermann Jun 16 '11 at 13:01
It's possible with the cooperation of the spawning object - it can write information into the Thread object (e.g. into the name of the thread, if you want a hacky way, or you could create a field for this purpose) that you could later use for debugging etc. But I don't think there's any 'built-in' way to get this info.

- 42,007
- 12
- 107
- 146
-
1*But I don't think there's any 'built-in' way to get this info*, SecurityManager was created exactly for that very reason, to trace calls to potentially security risk code. – bestsss Jun 16 '11 at 06:55
No, it's not possible. Probably the way to achieve this would be to have before
advice on Thread.start()
using AspectJ... Of course you can subclass Thread
, patch JDK code (different boot CLASSPATH), etc., but AspectJ seems to be the most portable and elegant solution.

- 334,321
- 69
- 703
- 674