Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] JoinPoint.getArgs() in multiple aspects on same joinpoint

Hi,

I have a situation where I have several possibly cascading Around advices as simplified below.

@Aspect
@Precedence(FirstAspect, *)
class FirstAspect{
	@Around("execution(@SomeAnnotation * *.foo(..))")
	public Object doAdvice(ProceedingJoinpoint jp) throws Throwable{
		Object [] args = jp.getArgs();
		for(int i=0;i<args.length : i++){
			if(args[i] instanceof BadArg){
				args[i] = new GoodArg();
			}
		}
		jp.proceed(args);
	}
}

@Aspect
class SecondAspect{
	@Around("execution(@SomeAnnotation * *(..))")
	public Object doAdvice(ProceedingJoinpoint jp) throws Throwable{
		Object [] args = jp.getArgs();
		// Gets the same args as returned from jp.getArgs() in FirstAspect,
		// not the modified ones.

		…. do something but have BadArg instead of GoodArg…..

		jp.proceed();
	}
}

FirstAspect may or may not appear before SecondAspect, SecondAspect is narrower.  I traced through the aspectj source and debugger, and I saw that both FirstAspect and SecondAspect have the same join point, whose args remain the original args passed in the target method call.  The args passed in to proceed I see go into state for the AroundClosures and the ones modified in FirstAspect do make it to the target method foo.  FirstAspect is correctly executing before SecondAspect.

I also see that JoinPoint.getArgs returns a copy of args rather than a reference.  And I've read a whole bunch on the web about binding args inside the join point using args.  However, this binding requires some name/pattern, and both FirstAspect, SecondAspect match to any method params (..).

So how can I modify things such that downstream aspects of FirstAspect will get the modified args passed by FirstAspect to JoinPoint.proceed?  Is there a way in the advice matching to bind to args(..) so I can get it as a reference in FirstAspect?  Or, can SecondAspect somehow get the AroundClosure state so it can look at those rather than JoinPoint.getArgs()?

In the meantime, I've just setup a globally accessible ThreadLocal<Map<JoinPoint, Object[]> variable that aspects (possibly) downstream of FirstAspect can lookup modified args and use those if they exist rather than the JoinPoint.getArgs().  This is pretty clunky workaround for the moment, I feel I am really missing something here.

Any help would be appreciated.

Thanks1

Jay Roberts

Back to the top