1

Is it possible to identify, probably using reflection, whether some method within a specific java class calls another method at build time?

Let's say that I have

  • ClassA that declares methodA1()
  • ClassB that declares methodB1(), methodB2(), methodB3()

I'd like to know, at build time, if any of ClassB's members call methodA1(). Is that possible?

I'm using JDK8 right now.

I'm surprised that I cannot find this question asked, which makes me think that it is very naive.

Thanks!

jdimmerman
  • 124
  • 4
  • 15
  • Do you want to know this at runtime, or compile time? – dan.m was user2321368 Feb 11 '19 at 23:15
  • Sorry, I need this at runtime, not compile time. I'm using it for some automated documentation across a number of libraries that use a shared package. I'll update the question. – jdimmerman Feb 11 '19 at 23:19
  • Do you need to know this without actually calling `methodB1` ? How about indirect calls (methodA -> methodC -> methodB) ? – Thilo Feb 11 '19 at 23:58
  • What do you need this at runtime? Documentation can be generated at build time, no? Given indirect calls, dynamic dispatch, reflection and the undecidability problem, I don't believe this is possible in the general case. Your best bet might be static analysis tools (such as used in an IDE to detect call graphs or for an obfuscator). – Thilo Feb 12 '19 at 00:01
  • You may find my answer here helpful: https://stackoverflow.com/a/51886800/1270000 My answer does talk about using it at compile time, but you can easily find this information as it occurs at runtime. Also consider swapping to Java9 or newer where you could use the stack walking api to find this information: https://stackoverflow.com/questions/421280/how-do-i-find-the-caller-of-a-method-using-stacktrace-or-reflection/45812871#45812871 – sorifiend Feb 12 '19 at 00:02
  • Sorry, yes I should say that I need to do this at build time, not at run time but also not within an IDE. I described it poorly. Will update again. I also need to do this without invoking any of the methods in either class. – jdimmerman Feb 12 '19 at 00:02
  • Thanks @sorifiend, I'll check it out shortly! – jdimmerman Feb 12 '19 at 00:03
  • Maybe Spring AOP can achieve that functionality. – LunaticJape Feb 12 '19 at 02:25
  • So unfortunately @sorifiend, I am not invoking methodA1() and so I never have a set of frames to traverse. (Assuming i am understanding your suggestion properly). – jdimmerman Feb 12 '19 at 13:33
  • Interesting @LunaticJape, thanks. I’ll check it out. – jdimmerman Feb 12 '19 at 13:36

1 Answers1

2

You could use

Thread.currentThread().getStackTrace()

Maybe this is not the best approach, since you have to dig in through the StackTraceElement array returned.

Angel D.
  • 162
  • 2
  • 11
  • You'd have to put that code into `methodA1` in your example. – Thilo Feb 11 '19 at 23:57
  • 1
    My understanding is that I can only do that from when the method itself is called. I'd like to be able to inspect a class and check if it *would* (at least potentially) call a method when invoked, rather than if the thread has called that method. – jdimmerman Feb 11 '19 at 23:58
  • Now I see... you're asking at build time... I read at runtime. I'm pretty sure your post said at runtime. – Angel D. Feb 12 '19 at 00:18