Answer above beat me to it, but I'd add that you might have to go through several stack frames before you get the class or method with 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 "Test" class...
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 output from 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 StackTraceUtil
for completeness. You see that I hard-coded "3" to get the the stace trace element from the array. You probably need to loop through everything from element 3 onwards until you find your annotation.
(This is not as elegant as the answer above, but as I'd nearly finished it I thought I'd post 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.