0

I want to retrieve the calling method where a specific method is called.
Example :
The method I consider :

public void methodA(int a, int b){...}

is called in a test method and also in the program itself

@Test
public void testMethodA(
... some code...
objectClassA.methodA(x,y);
)}

Class B {
...
 public void methodB(){
    objectClassA.methodA(x,y);
   }
}

What I want to obtain somehow is the inside or at least the signature of testMethodA and methodB

To do that I thought AspectJ could help me, so I looked into that and ended up writing this poincut
pointcut pcmethodA(): execution(* A.methodA(..) );

and my advice looked something like this

before(): pcmethodA() {
        System.out.println("[AspectJ] Entering " + thisJoinPoint);
        System.out.println("[AspectJ] Signature " + thisJoinPoint.getSignature());
        System.out.println("[AspectJ] SourceLocation "+ thisJoinPoint.getSourceLocation());

But this returns

[AspectJ] Entering execution(void com.example.somePackage.A.methodA(int, int)
[AspectJ] Signature com.example.somePackage.A.methodA(int, int)
[AspectJ] SourceLocation A.java:25   /** Line number of the methodA in the file **/

It is my first time using AspectJ , is there any object or way to retreive the calling method of my found joinpoints? testMethodA and methodB

Thanks

max152
  • 505
  • 1
  • 4
  • 6
  • 1
    You've not got the right tool for the job. It's not what AspectJ is for - it's not going to conjure up full call stacks. You will have to obtain and inspect thread stack traces. – M. Prokhorov Feb 12 '20 at 14:46
  • Indeed using the stacktrace might be a better solution. Thanks – max152 Feb 12 '20 at 15:52

1 Answers1

1

Let me recreate your situation first with a few sample classes + driver application:

package de.scrum_master.app;

public class Foo {
  public void methodA(int a, int b) {
    System.out.println("methodA: " + a + ", " + b);
  }
}
package de.scrum_master.app;

public class DummyTest {
  public void testSomething() {
    new Foo().methodA(33, 44);
  }
}
package de.scrum_master.app;

public class Application {
  public void doSomething() {
    new Foo().methodA(11, 22);
  }

  public static void main(String[] args) {
    new Application().doSomething();
    new DummyTest().testSomething();
  }
}

Now try call() in combination with thisEnclosingJoinPointStaticPart in your aspect:

package de.scrum_master.aspect;

import de.scrum_master.app.Foo;

public aspect MyAspect {
  pointcut pcmethodA() : call(* Foo.methodA(..));

  before() : pcmethodA() {
    System.out.println("[AspectJ] Executing: " + thisJoinPoint);
    System.out.println("[AspectJ] Called by: " + thisEnclosingJoinPointStaticPart);
  }
}

The console log when running Application:

[AspectJ] Executing: call(void de.scrum_master.app.Foo.methodA(int, int))
[AspectJ] Called by: execution(void de.scrum_master.app.Application.doSomething())
methodA: 11, 22
[AspectJ] Executing: call(void de.scrum_master.app.Foo.methodA(int, int))
[AspectJ] Called by: execution(void de.scrum_master.app.DummyTest.testSomething())
methodA: 33, 44

See? No need to juggle stack traces if you just want to determine caller and callee.

kriegaex
  • 63,017
  • 15
  • 111
  • 202
  • Looks great indeed but in my case it gives the same result for both thisJoinPoint and thisEnclosingJoinPointStaticPart (?). My context is that I run the app only using 'mvn test' command. Stacktrace manipulation method however is correct, using the same program. – max152 Feb 13 '20 at 10:04
  • If it gives the same result, you probably still use `execution()` instead of `call()` as suggested by me. Please next time read my answer more carefully. – kriegaex Feb 13 '20 at 10:30
  • Indeed, my mistake. I was somehow mentally stuck on the 'execution' type pointcut... Thanks – max152 Feb 13 '20 at 14:23