public static Method getMethod()

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);
  }