I am using Eclipse IDE for my Java project. I need a list of methods which are being called from a particular class i.e. I need to see a list of all the methods which are being called from a class but not declared in that. I am looking for some option which might be there in Eclipse already. I am not willing to write a code for this (that will be my last choice).
Let me explain using this example -
public class ABC {
public void methodA {
System.out.println("In methodA");
BCD bcd = new BCD();
bcd.callMethodAA(); // defined in class BCD
}
public void methodB {
System.out.println("In methodB");
CDE cde = new CDE();
cde.callMethodBB(); // defined in class CDE
}
}
I want an option which will show me -
From Class ABC we are calling -
a) callMethodAA
b) callMethodBB
If you need to list only the method being used, there is no in-language way to achieve that. Though there might be some coverage tools which can handle this.
But If its about all the available methods, you can use reflection:
Class<?> cls = Class.forName("className");
Method[] methodList = cls.getMethods();
To find the methods that are called from a class (assuming programatically), I would use the ASM bytecode analyzing/manipulation library. The below example is a ClassVisitor
that prints all the methods called from a class.
import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.commons.InstructionAdapter;
public class MethodCallFinder extends ClassAdapter {
private String name;
public MethodCallFinder(ClassVisitor classVisitor) {
super(classVisitor);
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
this.name = name;
super.visit(version, access, name, signature, superName, interfaces);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
return new MethodCallPrinter(super.visitMethod(access, name, desc, signature, exceptions));
}
private class MethodCallPrinter extends InstructionAdapter {
public MethodCallPrinter(MethodVisitor methodVisitor) {
super(methodVisitor);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
System.out.printf("Class %s calls method %s with descriptor %s from class %s%n", MethodCallFinder.this.name, name, desc, owner);
super.visitMethodInsn(opcode, owner, name, desc);
}
}
}
You can do it by creating a single method that invokes all the methods on your class. If you already have one of those even better. Take the Logo.java class from Junit as an example if I create this:
private void ExposeAllCalledMethods()
{
Logo x = new Logo();
x.loadImage("something");
Graphics g;
x.paint(g);
}
Note I didn't need to call paintBackround() because paint() already calls it.
Then I can right-click in the method name ExposeAllCalledMethods and select Open Call Hierarchy. Then in the call hierarchy window click on the Callees button (see the green arrow in the image) and open all the gray hierarchy arrows as shown in the image below. A complete list of all methods called by the current class is shown.
<Shameless Plug> Now I wish I had shown how to do this in my new Pluralsight Eclipse course. </Shameless Plug>
.
In Eclipse, you can do this by selecting (highlighting) the method in an editor pane, then constructing the Call Hierarchy (probably Ctrl-Alt-h). You can then switch from "Show Caller Hierarchy" (default) to "Show Callee Hierarchy" using the toggle buttons in the top-right of the Call Hierarchy pane. The one you want looks like sideways tree with children to the right, like o-[ not ]-o.
str + o
lists all methods available in the class that is currently open.
does this answer your question?
If it is at runtime, you could use a Dynamic Proxy.
The dynamic proxy is called before the method invocations of your class and you can log somewhere (to another class, or a file or whatever) which methods have been called.
The answer dependents on the context:
If you like to have this for your code within your IDE: This depends on the IDE. In Eclipse, I believe, it is not possible. You can get the method which calls a given class (constructor of method) via "Open Call Hierarchy".
If you like to do it at runtime: This is solvable with AspectJ, see for example http://www.eclipse.org/aspectj/doc/released/progguide/language-thisJoinPoint.html (at the end there is a piece to get the caller of any method).