Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proceed with variable arguments with AspectJ

Tags:

java

aspectj

I'm trying to normalize URIs across an application using AspectJ. I'm catching every call that is made to a method passing in a java.net.URI parameter using this code:

Object around() : execution(* *(..,java.net.URI,..)) {
    for ( Object arg : thisJoinPoint.getArgs() ) {
        if ( arg instanceof URI ) {
            // normalize
        }
    }
    return proceed();
}

However, since URI is immutable, I can't swap in the normalized value into the existing object. What I need is to call proceed with the new, normalized URI objects (and possibly passing along the other arguments unchanged). However, the proceed call only lets me pass along arguments that were collected by the join point. Is there any way to accomplish this for a variable number of arguments (mostly being interested in any URI argument(s), but willing to collect and pass along all arguments)?

like image 731
Adam Avatar asked Aug 30 '11 14:08

Adam


2 Answers

You need to change your advice's signature:

Object around(Object[] args) : execution(* *(..,java.net.URI,..)) && args(args) {
    for(int i = 0; i < args.length; i++){
        Object arg = args[i];
        if ( arg instanceof URI ) {
            args[i] = normalizeUrI((URI)arg);
        }
    }
    return proceed(args);
}

Update: the above code doesn't work unfortunately. But this should:

Object around() throws URISyntaxException : execution(* **.*(..,URI,..)) {
    final Object[] args = thisJoinPoint.getArgs();
    for(int i = 0; i < args.length; i++){
        final Object arg = args[i];
        if ( arg instanceof URI ) {
            args[i] = normalizeUrI((URI)arg);
        }
    }
    try{
        return ((ProceedingJoinPoint)thisJoinPoint).proceed(args);
    } catch(final Throwable e){
        throw new IllegalStateException(e);
    }
}
like image 133
Sean Patrick Floyd Avatar answered Oct 06 '22 15:10

Sean Patrick Floyd


What follows should be a comment not a full answer but my limited rep doesn't allow me to comment...

The code in the question and also in the answer by Sean Patrick Floyd won't work because there can only be one occurrence of the wildcard ".." in a method signature pattern. A short explanation of why it is so can be found here.

like image 37
Raul Bertone Avatar answered Oct 06 '22 15:10

Raul Bertone