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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With