Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I find all the methods that call a given method in Java?

Tags:

java

I need to get a list of all caller methods for a method of interest for me in Java. Is there a tool that can help me with this?

Edit: I forgot to mention that I need to do this from a program. I'm usig Java Pathfinder and I want to run it an all the methods that call my method of interest.

like image 299
arthur Avatar asked May 30 '09 18:05

arthur


People also ask

How many ways can a method be called in Java?

Method Calling There are two ways in which a method is called i.e., method returns a value or returning nothing (no return value). the return statement is executed.

How do you call a method from a method in Java?

A method must be created in the class with the name of the method, followed by parentheses (). The method definition consists of a method header and method body. We can call a method by using the following: method_name(); //non static method calling.

Where can I find method references in eclipse?

Right click and select References > Project or References > Workspace from the pop-up menu. Show activity on this post. This will show you a Search view containing the hierarchy of class and method which using this method.

How do you identify a method in Java?

While defining a method, remember that the method name must be a verb and start with a lowercase letter. If the method name has more than two words, the first name must be a verb followed by an adjective or noun. In the multi-word method name, the first letter of each word must be in uppercase except the first word.

How do I know if a method is called in Java?

If your method implements a method from an interface or base class, you can only know that your method is POSSIBLY called. A lot of Java frameworks use Reflection to call your method (IE Spring, Hibernate, JSF, etc), so be careful of that. On the same note, your method could be called by some framework, reflectively or not, so again be careful.

How to call two methods with the same name in Java?

A class can contain two or more methods with the same name. Now a question arises that how we can call two methods with the same name. When a class has two or more methods with the same name it is differentiated by either return type or types of parameter or number of parameters. This concept is called method overloading.

How to view all methods that call a method in Eclipse?

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).

How to programtically find callers and callees 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.


1 Answers

For analyzing bytecode, I would recommend ASM. Given a list of Classes to analyze, a visitor can be made which finds the method calls you're interested in. One implementation which analyses classes in a jar file is below.

Note that ASM uses internalNames with '/' instead of '.' as a separator. Specify the target method as a standard declaration without modifiers.

For example, to list methods that could be calling System.out.println("foo") in the java runtime jar:

java -cp "classes;asm-3.1.jar;asm-commons-3.1.jar" App \     c:/java/jdk/jre/lib/rt.jar \     java/io/PrintStream  "void println(String)" 

Edit: source and line numbers added: Note that this only indicates the last target method invocation per calling method - the original q only wanted to know which methods. I leave it as an exercise for the reader to show line numbers of the calling method declaration, or the line numbers of every target invocation, depending on what you're actually after. :)

results in:

LogSupport.java:44 com/sun/activation/registries/LogSupport log (Ljava/lang/String;)V LogSupport.java:50 com/sun/activation/registries/LogSupport log (Ljava/lang/String;Ljava/lang/Throwable;)V ... Throwable.java:498 java/lang/Throwable printStackTraceAsCause (Ljava/io/PrintStream;[Ljava/lang/StackTraceElement;)V -- 885 methods invoke java/io/PrintStream println (Ljava/lang/String;)V 

source:

public class App {     private String targetClass;     private Method targetMethod;      private AppClassVisitor cv;      private ArrayList<Callee> callees = new ArrayList<Callee>();      private static class Callee {         String className;         String methodName;         String methodDesc;         String source;         int line;          public Callee(String cName, String mName, String mDesc, String src, int ln) {             className = cName; methodName = mName; methodDesc = mDesc; source = src; line = ln;         }     }      private class AppMethodVisitor extends MethodAdapter {          boolean callsTarget;         int line;          public AppMethodVisitor() { super(new EmptyVisitor()); }          public void visitMethodInsn(int opcode, String owner, String name, String desc) {             if (owner.equals(targetClass)                     && name.equals(targetMethod.getName())                     && desc.equals(targetMethod.getDescriptor())) {                 callsTarget = true;             }         }          public void visitCode() {             callsTarget = false;         }          public void visitLineNumber(int line, Label start) {             this.line = line;         }          public void visitEnd() {             if (callsTarget)                 callees.add(new Callee(cv.className, cv.methodName, cv.methodDesc,                          cv.source, line));         }     }      private class AppClassVisitor extends ClassAdapter {          private AppMethodVisitor mv = new AppMethodVisitor();          public String source;         public String className;         public String methodName;         public String methodDesc;          public AppClassVisitor() { super(new EmptyVisitor()); }          public void visit(int version, int access, String name,                           String signature, String superName, String[] interfaces) {             className = name;         }          public void visitSource(String source, String debug) {             this.source = source;         }          public MethodVisitor visitMethod(int access, String name,                                           String desc, String signature,                                          String[] exceptions) {             methodName = name;             methodDesc = desc;              return mv;         }     }       public void findCallingMethodsInJar(String jarPath, String targetClass,                                         String targetMethodDeclaration) throws Exception {          this.targetClass = targetClass;         this.targetMethod = Method.getMethod(targetMethodDeclaration);          this.cv = new AppClassVisitor();          JarFile jarFile = new JarFile(jarPath);         Enumeration<JarEntry> entries = jarFile.entries();          while (entries.hasMoreElements()) {             JarEntry entry = entries.nextElement();              if (entry.getName().endsWith(".class")) {                 InputStream stream = new BufferedInputStream(jarFile.getInputStream(entry), 1024);                 ClassReader reader = new ClassReader(stream);                  reader.accept(cv, 0);                  stream.close();             }         }     }       public static void main( String[] args ) {         try {             App app = new App();              app.findCallingMethodsInJar(args[0], args[1], args[2]);              for (Callee c : app.callees) {                 System.out.println(c.source+":"+c.line+" "+c.className+" "+c.methodName+" "+c.methodDesc);             }              System.out.println("--\n"+app.callees.size()+" methods invoke "+                     app.targetClass+" "+                     app.targetMethod.getName()+" "+app.targetMethod.getDescriptor());         } catch(Exception x) {             x.printStackTrace();         }     }  } 
like image 132
Chadwick Avatar answered Oct 06 '22 07:10

Chadwick