Java: Find all callers of a method – get all methods that call a particular method
I will explore how we can compute fan in i.e. find all the methods that call a particular method (all callers of a method).
In Eclipse, one can right click on a method and choose «open call hierarchy» and eclipse shows all the methods that call the selected method and all the methods that are called from the selected method (callers and callees of the selected method).
We can programtically find callers and callees and I will explain how I have done it.
There are a couple of different ways that I know:
- Use the eclipse JDT internal classes : these are the same classes used by eclipse to show the callers and callees of a method
- Use the eclipse ast visitor
In this post, I will discuss how we can use the eclipse JDT internal classes to find callers and callees of a method.
Firstly, import the following classes (as you can see they are in an «internal» package!)
import org.eclipse.jdt.internal.corext.callhierarchy.CallHierarchy; import org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper;
import org.eclipse.jdt.internal.corext.callhierarchy.CallHierarchy; import org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper;
Write a methodgetCallersOf that takes the selected method as an input [IMethod]. This will be your API type method, you should call this method from your program for any method whose callers you wish to find.
The crucial part of the code is to first get the default CallHierarchy object, use this CallHierarchy object to get the caller-roots of the input IMethod, and for each method-wrapper object that is returned, invoke the getCalls method. getCalls in turn returns an array of MethodWrapper objects and these are the actual callers. From each MethodWrapper object, we can get a corresponding IMethod.
public HashSetIMethod> getCallersOf(IMethod m) { CallHierarchy callHierarchy = CallHierarchy.getDefault(); IMember[] members = {m}; MethodWrapper[] methodWrappers = callHierarchy.getCallerRoots(members); HashSetIMethod> callers = new HashSetIMethod>(); for (MethodWrapper mw : methodWrappers) { MethodWrapper[] mw2 = mw.getCalls(new NullProgressMonitor()); HashSetIMethod> temp = getIMethods(mw2); callers.addAll(temp); } return callers; } HashSetIMethod> getIMethods(MethodWrapper[] methodWrappers) { HashSetIMethod> c = new HashSetIMethod>(); for (MethodWrapper m : methodWrappers) { IMethod im = getIMethodFromMethodWrapper(m); if (im != null) { c.add(im); } } return c; } IMethod getIMethodFromMethodWrapper(MethodWrapper m) { try { IMember im = m.getMember(); if (im.getElementType() == IJavaElement.METHOD) { return (IMethod)m.getMember(); } } catch (Exception e) { e.printStackTrace(); } return null; }
public HashSet getCallersOf(IMethod m) < CallHierarchy callHierarchy = CallHierarchy.getDefault(); IMember[] members = ; MethodWrapper[] methodWrappers = callHierarchy.getCallerRoots(members); HashSet callers = new HashSet(); for (MethodWrapper mw : methodWrappers) < MethodWrapper[] mw2 = mw.getCalls(new NullProgressMonitor()); HashSettemp = getIMethods(mw2); callers.addAll(temp); > return callers; > HashSet getIMethods(MethodWrapper[] methodWrappers) < HashSetc = new HashSet(); for (MethodWrapper m : methodWrappers) < IMethod im = getIMethodFromMethodWrapper(m); if (im != null) < c.add(im); >> return c; > IMethod getIMethodFromMethodWrapper(MethodWrapper m) < try < IMember im = m.getMember(); if (im.getElementType() == IJavaElement.METHOD) < return (IMethod)m.getMember(); >> catch (Exception e) < e.printStackTrace(); >return null; >
Related posts:
If you want someone to read your code, please put the code inside
and
tags. For example:
https://uploads.disquscdn.com/images/0454ff7885cb0771470fcf4eae3ad819645c1f84473b43558fcbe46324db859d.png But after doing all, one will ger ‘Workspace Closed’ error. Any pointer appreciated. Exception in thread “main” java.lang.IllegalStateException: Workspace is closed.
at org.eclipse.core.resources.ResourcesPlugin.getWorkspace(ResourcesPlugin.java:412)
at util.FindAllMethodInWorkspace.processRootDirectory(FindAllMethodInWorkspace.java:32)
at util.FindAllMethodInWorkspace.main(FindAllMethodInWorkspace.java:20)
Thank you for your helpful article .
However , My project is written in J2SE 1.3 version and i cannot change the version because of hardware reasons.Do you have any idea or any technique for finding all callers of a method in java 1.3 version.Could you please to help me answer the following question?
hi,
i’m trying to analyse the JHotDraw project to calculate the fan in metric, but i’m getting a java.lang.nullPointerException @ this line MethodWrapper[] mw2 = mw.getCalls(new NullProgressMonitor()); org.eclipse.e4.core.di.InjectionException: java.lang.NullPointerException
at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:63)
at org.eclipse.e4.core.internal.di.InjectorImpl.invokeUsingClass(InjectorImpl.java:231)
at org.eclipse.e4.core.internal.di.InjectorImpl.invoke(InjectorImpl.java:212)
at org.eclipse.e4.core.contexts.ContextInjectionFactory.invoke(ContextInjectionFactory.java:131)
at org.eclipse.e4.core.commands.internal.HandlerServiceImpl.executeHandler(HandlerServiceImpl.java:171)
at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.executeItem(HandledContributionItem.java:831)
at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.handleWidgetSelection(HandledContributionItem.java:724)
at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.access$7(HandledContributionItem.java:708)
at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem$4.handleEvent(HandledContributionItem.java:647)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4169)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3758)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1053)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:942)
at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:86)
at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:588)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:543)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
at org.eclipse.equinox.launcher.Main.main(Main.java:1414)
Caused by: java.lang.NullPointerException
at org.eclipse.jdt.internal.core.search.matching.ClasspathSourceDirectory.directoryTable(ClasspathSourceDirectory.java:44)
at org.eclipse.jdt.internal.core.search.matching.ClasspathSourceDirectory.findClass(ClasspathSourceDirectory.java:84)
at org.eclipse.jdt.internal.core.search.matching.JavaSearchNameEnvironment.findClass(JavaSearchNameEnvironment.java:146)
at org.eclipse.jdt.internal.core.search.matching.JavaSearchNameEnvironment.findType(JavaSearchNameEnvironment.java:185)
at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.askForType(LookupEnvironment.java:145)
at org.eclipse.jdt.internal.compiler.lookup.PackageBinding.getTypeOrPackage(PackageBinding.java:197)
at org.eclipse.jdt.internal.compiler.lookup.Scope.getTypeOrPackage(Scope.java:2795)
at org.eclipse.jdt.internal.compiler.lookup.Scope.getType(Scope.java:2513)
at org.eclipse.jdt.internal.core.search.matching.MatchLocator.getType(MatchLocator.java:899)
at org.eclipse.jdt.internal.core.search.matching.MatchLocator.getMethodBinding0(MatchLocator.java:955)
at org.eclipse.jdt.internal.core.search.matching.MatchLocator.getMethodBinding(MatchLocator.java:907)
at org.eclipse.jdt.internal.core.search.matching.MethodLocator.matchMethod(MethodLocator.java:327)
at org.eclipse.jdt.internal.core.search.matching.MethodLocator.resolveLevel(MethodLocator.java:664)
at org.eclipse.jdt.internal.core.search.matching.ClassFileMatchLocator.locateMatches(ClassFileMatchLocator.java:209)
at org.eclipse.jdt.internal.core.search.matching.MatchLocator.process(MatchLocator.java:1697)
at org.eclipse.jdt.internal.core.search.matching.MatchLocator.locateMatches(MatchLocator.java:1141)
at org.eclipse.jdt.internal.core.search.matching.MatchLocator.locateMatches(MatchLocator.java:1182)
at org.eclipse.jdt.internal.core.search.matching.MatchLocator.locateMatches(MatchLocator.java:1299)
at org.eclipse.jdt.internal.core.search.JavaSearchParticipant.locateMatches(JavaSearchParticipant.java:95)
at org.eclipse.jdt.internal.core.search.BasicSearchEngine.findMatches(BasicSearchEngine.java:231)
at org.eclipse.jdt.internal.core.search.BasicSearchEngine.search(BasicSearchEngine.java:515)
at org.eclipse.jdt.core.search.SearchEngine.search(SearchEngine.java:584)
at org.eclipse.jdt.internal.corext.callhierarchy.CallerMethodWrapper.findChildren(CallerMethodWrapper.java:155)
at org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper.performSearch(MethodWrapper.java:301)
at org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper.doFindChildren(MethodWrapper.java:232)
at org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper.getCalls(MethodWrapper.java:84)
at projet.aspectm.plug.handler.ExtractHandler.getCallersOf(ExtractHandler.java:206)
at projet.aspectm.plug.handler.ExtractHandler.printIMethodDetails(ExtractHandler.java:174)
at projet.aspectm.plug.handler.ExtractHandler.printIMethods(ExtractHandler.java:121)
at projet.aspectm.plug.handler.ExtractHandler.printCompilationUnitDetails(ExtractHandler.java:137)
at projet.aspectm.plug.handler.ExtractHandler.printICompilationUnitInfo(ExtractHandler.java:112)
at projet.aspectm.plug.handler.ExtractHandler.printPackageInfos(ExtractHandler.java:99)
at projet.aspectm.plug.handler.ExtractHandler.execute(ExtractHandler.java:68)
at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:290)
at org.eclipse.ui.internal.handlers.E4HandlerProxy.execute(E4HandlerProxy.java:76)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:56)
… 34 more
I used reflection to get all classes and methods from a given java project
with the method : class.getDeclaredMethods(); I want to get the callers of each method in this list or if I can do the same thing with the API org.eclipse.jdt.core or if I can find an IMethod from the method name (string) to finally use the code you proposed thank you very much for your reply ^_^
Java get calling methods
- Language
- HTML & CSS
- Form
- Java interaction
- Mobile
- Varia
- Language
- String / Number
- AWT
- Swing
- Environment
- IO
- JS interaction
- JDBC
- Thread
- Networking
- JSP / Servlet
- XML / RSS / JSON
- Localization
- Security
- JNI / JNA
- Date / Time
- Open Source
- Varia
- Powerscript
- Win API & Registry
- Datawindow
- PFC
- Common problems
- Database
- WSH & VBScript
- Windows, Batch, PDF, Internet
- BigIndex
- Download
- TS2068, Sinclair QL Archives
- Real’s HowTo FAQ
- Donate!
- Funny 1
- Funny 2
- Funny 3
- Funny 4
- One line
- Ascii Art
- Deprecated (old stuff)
Get the current or calling method name Tag(s): Language
About cookies on this site
We use cookies to collect and analyze information on site performance and usage, to provide social media features and to enhance and customize content and advertisements.
JDK1.4+
public class MyTest < public static void main(String args[]) < new MyTest().doit(); >public void doit() < System.out.println (new Exception().getStackTrace()[0].getMethodName()); // output :doit >>
JDK1.5+
While the above snippet is not bad, it is expensive since we need to create an Exception each time we needa trace.
With JDK1.5, a better technique is available to get the current method.
public class Test < public static void main(String args[]) < trace(Thread.currentThread().getStackTrace()); // output :main new Test().doit(); trace(Thread.currentThread().getStackTrace()); // output :main >public void doit() < trace(Thread.currentThread().getStackTrace()); // output :doit doitagain(); >public void doitagain() < trace(Thread.currentThread().getStackTrace()); // output : doitagain >public static void trace(StackTraceElement e[]) < boolean doNext = false; for (StackTraceElement s : e) < if (doNext) < System.out.println(s.getMethodName()); return; >doNext = s.getMethodName().equals("getStackTrace"); > > >
Now we know how to get the current method. If we need the calling instead instead :
public class Test < public static void main(String args[]) < new Test().doit(); >public void doit() < System.out.println( Thread.currentThread().getStackTrace()[2].getMethodName()); // output : main >>