in feline/src/main/java/com/spotify/feline/BytecodeUtils.java [87:147]
public static Method getMethod(final StackTraceElement stackTraceElement) throws Exception {
final String stackTraceClassName = stackTraceElement.getClassName();
final String stackTraceMethodName = stackTraceElement.getMethodName();
final int stackTraceLineNumber = stackTraceElement.getLineNumber();
final Class<?> stackTraceClass = Class.forName(stackTraceClassName);
final String classFileResourceName =
"/" + stackTraceClassName.replaceAll("\\.", "/") + ".class";
final InputStream classFileStream = stackTraceClass.getResourceAsStream(classFileResourceName);
if (classFileStream == null) {
throw new RuntimeException(
"Could not acquire the class file containing for the calling class");
}
final AtomicReference<String> methodDescriptorReference = new AtomicReference<>();
try {
final ClassReader classReader = new ClassReader(classFileStream);
classReader.accept(
new ClassVisitor(OpenedClassReader.ASM_API) {
@Override
public MethodVisitor visitMethod(
int access,
final String name,
final String desc,
String signature,
String[] exceptions) {
if (!name.equals(stackTraceMethodName)) {
return null;
} else {
return new MethodVisitor(OpenedClassReader.ASM_API) {
@Override
public void visitLineNumber(int line, Label start) {
if (line == stackTraceLineNumber) {
methodDescriptorReference.set(desc);
}
}
};
}
}
},
0);
} finally {
classFileStream.close();
}
String methodDescriptor = methodDescriptorReference.get();
if (methodDescriptor == null) {
throw new RuntimeException("Could not find line " + stackTraceLineNumber);
}
for (Method method : stackTraceClass.getDeclaredMethods()) {
if (stackTraceMethodName.equals(method.getName())
&& methodDescriptor.equals(Type.getMethodDescriptor(method))) {
return method;
}
}
throw new RuntimeException("Could not find the calling method " + stackTraceMethodName);
}