Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access a business method's local variable in a method which is in an ASPECT

I want to access a local variable from a method in a business class, in a method which is in an aspect class. For instance

class BusinessClass {
    public void simpleTest() {
        ...
        String localString = new String( "test" );
        ...
    }
} 

MyAspect {
    log() {
        // I WANT TO ACCESS THE VALUE OF LOCALSTRING HERE
    }
}

I want to access localString's value in log method of MyAspect. Please let me know if there is any way to accomplish this using Spring / AspectJ. Also, is there is a way to accomplish without changing simpleTest method signature?

Thanks much in advance!

like image 646
lupchiazoem Avatar asked Apr 02 '11 08:04

lupchiazoem


2 Answers

Unfortunately, local variables are not exposed via joinpoints. This means that you cannot write a pointcut to match them. So, the answer is no, you cannot do this directly.

However, if you were to refactor your code so that the local variable were created inside of a method, then you could access it.

Conceptually, this kind of refactoring might be better for you code. Rather than simply allocate a new local variable, you can be explicit about what the allocation is doing by encapsulating it in a well-named method.

For example, this:

String localString = new String( "test" );

becomes this:

String localString = allocateTestString();  // or some better name

With this method:

private String allocateTestString() { 
    return new String( "test" )
}

Then you can write a pointcut to capture the local variable this way:

after() returning(String var) : call(private String allocateTestString()) {
     // do something fun
}
like image 83
Andrew Eisenberg Avatar answered Oct 17 '22 03:10

Andrew Eisenberg


As I understand them, aspects are intended to be applicable to many methods (as defined by the pointcut). As such, they don't see the internals of the method: just the arguments to the method and the result from it. This means that what you want can't be done directly, but you could try refactoring your method into two pieces, one that takes the localString as an argument, and the other which applies a default value to it. That will then give you a nice convenient joint point to attach to. (The AspectJ reference lists join points, and references to local variables aren't one of them.) If you make the “inner” method private or package-private, you won't even change the generally-understood signature of the method (since external code won't be able to depend on the introduced method).

like image 22
Donal Fellows Avatar answered Oct 17 '22 02:10

Donal Fellows