The answer above beat me up, but I would add that you have to go through a few frames of the stack before you get the class or method using the annotations you are looking for, even if the source code is in the same class (but you probably know this) .
For example, here was my class "Test" ...
import javassist.CtMethod; public class Test { private void method(String s) { called(); } private void method() { called(); } private static void called() { CtMethod caller = StackTraceUtil.getCaller(); System.out.println(caller); } private interface Widgit { void call(); } private static void call(Widgit w) { w.call(); } public static void main(String[] args) { new Test().method(); new Test().method("[]"); new Widgit() { @Override public void call() { called(); } }.call(); call(() -> { called(); }); } }
The way out of this was ...
javassist.CtMethod@e59521a2 [private method ()V] javassist.CtMethod@abb88b98 [private method (Ljava/lang/String;)V] javassist.CtMethod@bbd779f1 [static access$0 ()V] javassist.CtMethod@67f92ed4 [private static lambda$0 ()V]
Here's the StackTraceUtil for completeness. You see, I hardcoded "3" to get the stace trace element from the array. You probably need to go through everything from element 3 until you find your annotation.
(This is not as elegant as the answer above, but as I was almost done, I thought I would send it anyway ...)
import java.util.HashMap; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod; import javassist.NotFoundException; public class StackTraceUtil { private static Map<Class<?>, SortedMap<Integer, CtMethod>> cache = new HashMap<>(); public static CtMethod getCaller() { StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace(); StackTraceElement stackTraceElement = stacktrace[3]; int lineNumber = stackTraceElement.getLineNumber(); try { return findMethod(Class.forName(stackTraceElement.getClassName()), lineNumber); } catch (ClassNotFoundException e) { return null; } } public static CtMethod findMethod(Class<?> clazz, int lineNumber) { SortedMap<Integer, CtMethod> classInfo = cache.get(clazz); if (classInfo == null) { classInfo = populateClass(clazz); cache.put(clazz, classInfo); } if(classInfo != null) { SortedMap<Integer, CtMethod> map = classInfo.tailMap(lineNumber); if(!map.isEmpty()) { return map.values().iterator().next(); } } return null; } private static SortedMap<Integer, CtMethod> populateClass(Class<?> clazz) { SortedMap<Integer, CtMethod> result; try { ClassPool pool = ClassPool.getDefault(); CtClass cc = pool.get(clazz.getCanonicalName()); CtMethod[] methods = cc.getDeclaredMethods(); result = new TreeMap<>(); for (CtMethod ctMethod : methods) { result.put(ctMethod.getMethodInfo().getLineNumber(0), ctMethod); } } catch (NotFoundException ex) { result = null; } return result; } }
Hope this helps.
Bretc source share