1

I have an app with many endpoints. I made a change to functionWhoIsCallingMe(). I want to find which controller endpoints call this function (directly or hierarchically) so I can test it.

@RequestMapping("/a")
someEndpoint(){
 anyFunction()
}

@RequestMapping("/b")
anotherEndpoint(){
 functionWhoIsCallingMe()
}

anyFunction(){
  functionWhoIsCallingMe()
}

Given this code I want to know ["/a", "/b"] is calling functionWhoIsCallingMe().

I tried "Call Hierarchy" but that's not practical here because it would take to long to open all the tabs. I also tried filtering like suggested here, but that doesn't work because you can only specify one type of class to NOT match and if it doesn't match it wont show the calling method. I can't say only show files with Controller in the file name.

Philip Rego
  • 552
  • 4
  • 20
  • 35
  • 2
    What do you mean by *"it would take to long to open all the tabs"*? Using the call hierarchy is the answer to "who calls the method". – Andreas Apr 21 '21 at 20:40
  • 1
    Have you tried writing log entries or stepping through with the debugger? – DLynch Apr 21 '21 at 20:41
  • 1
    @Andreas I asked how to find who calls the method *easily*. If you use Call Hierarchy on a function that's called a few places the Call Hierarchy is very big. If i want to find what I'm looking for I'd have to open every tab because controller is only shown after last tab is open. Would take hours to open all the tabs and check. – Philip Rego Apr 21 '21 at 20:45
  • 1
    By "open every tab" you're talking about *expanding* the *nodes* in the call hierarchy *tree*? Unless you have thousands of lines of code that calls the method, I don't see how it can *"take hours to open"*, since it takes less than 1 second to expand a node. – Andreas Apr 21 '21 at 20:49
  • 1
    @DLynch For that to work I'd have to call every endpoint in my app with every possible parameter combination. I don't have calls for all the endpoints readily availible. To write calls for all of them would be to much work. – Philip Rego Apr 21 '21 at 20:49
  • *FYI:* You can expand an entire subtree in call hierarchy pane by selecting the node and pressing `*`. – Andreas Apr 21 '21 at 20:53
  • 1
    @Andreas yes. * doesn't work in my Eclipse. When Call Hierarchy is first called on my method there's 7 nodes. In the first node I had to open 29 tabs. So there's about 29*7=203 tabs I'd have to open and find the last node of each without accidentaly closing anything. Maybe would take an hour to do wish someone had an easier way. – Philip Rego Apr 21 '21 at 21:00
  • So wait, there are 7 call stacks that are *each* 29 calls deep that converge on your method? – DLynch Apr 21 '21 at 21:23
  • ya 7 functions call my function Those 7 functions are called by x many functions which are called by y many functions, ect until controller. I'll admit there's more function calls than normal in this project. Lots of methods with same name different parms calling each other for no good reason like `addUser(User u){ addUser(u, null) }` – Philip Rego Apr 21 '21 at 22:40
  • 1
    @DLynch if there was a log in the function and the log shows the calling endpoint then I could see which endpoints are calling the method. There's no log in my function unfortunatly. – Philip Rego Apr 22 '21 at 02:03
  • 1
    Still looking for an answer. Would be super helpful if I could give two function names and see the call hierarchy between then. – Philip Rego May 11 '21 at 19:01
  • I would just add that you having a logging in those methods of interest might not be the right approach, unless you have ideal test coverage. Imagine those calls are only conditional (i.e. only called with certain input values/parameters.) – Jaroslav Záruba Sep 01 '22 at 09:53

1 Answers1

-1
@RequestMapping("/b")
public void someEndpoint() {
    anyFunction(1);
}
@RequestMapping("/b")
public void anotherEndpoint() {
    functionWhoIsCallingMe(1);
}

public void anyFunction(int val/** init val=1*/) {
    functionWhoIsCallingMe(val + 1);
}

public void functionWhoIsCallingMe(int val/** init val=1*/) {
    try {
        final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
        String defName = ste[val + 1].getMethodName();
        String[] path = this.getClass().getMethod(defName).getAnnotation(RequestMapping.class).value();
        System.out.println("Url path:" + path[0]);
    } catch (Exception ex) {
    }
}