2

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

Saikat
  • 14,222
  • 20
  • 104
  • 125
  • Do you want to know at which methods of a class was called by any other class during runtime? – fancy Aug 14 '13 at 13:09
  • Reading your question, it is not clear what you are trying to accomplish... Are you trying to log the methods that are being called? Take a look at AOP approaches. Are you trying to follow the execution of a particular instance in real time? Use a debugger. Are you trying to know (statically) which methods are being called by other classes of your application and at what line of code? Take a look at the call hierarchy for that particular method. – Anthony Accioly Aug 14 '13 at 13:13
  • Question edited. Does it make sense now? – Saikat Aug 14 '13 at 13:44
  • Not quite... It is clear that you want a static option which lists method dependencies... Is your exact need something like "Given class `A` list all methods of other classes called in `A`"? If so, take a look at: http://stackoverflow.com/questions/6530750/eclipse-see-which-methods-of-one-class-are-used-in-another – Anthony Accioly Aug 14 '13 at 14:33
  • @Anthony Accioly: Call Hierarchy is the opposite direction. Get the calling methods. He likes to get the called methods. - See my answer below. – Christian Fries Aug 14 '13 at 14:55

6 Answers6

4

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();
rocketboy
  • 9,573
  • 2
  • 34
  • 36
  • You could find out when a method does get invoked using CGLIB though. Although I am unsure if the OP is asking for all methods in a class (whether declared or inherited from superclass) or if he wants to know when a method is called. – Josh M Aug 14 '13 at 13:12
  • I just want to know - what all methods I am calling from my class which are declared in some other class. Also, I want to achieve this by using some option present in Eclipse e.g. as we see Outline to get the list of all members of a class. – Saikat Aug 14 '13 at 13:29
3

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);
        }
    }
}
Sam Marsh
  • 166
  • 2
  • 6
1

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>

Hierarchy window showing all called methods.

Tod
  • 8,192
  • 5
  • 52
  • 93
  • That's interesting but still does not answer my query. Let me re-edit my question. – Saikat Aug 15 '13 at 05:13
  • Yes, I realize it has two flaws, one is you have to add a tramp method, the other is it includes methods from the current class. The latter problem is mitigated a little by the fact that you can easily see the full class name, ie. junit.awtui.Logo to the right. I don't see a way around the former problem yet. – Tod Aug 15 '13 at 18:41
  • Thank you very much! That was exactly what I needed! – Ahmed Rezk Mar 09 '17 at 09:49
1

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.

laloumen
  • 1,229
  • 2
  • 14
  • 15
0

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.

fancy
  • 2,077
  • 2
  • 23
  • 45
0

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

Christian Fries
  • 16,175
  • 10
  • 56
  • 67