Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] around advice and modifying arguments


Peter,

To modify method arguments you need to use around advice with proceed (as you have tried). Unfortunately thisJoinPoint is read-only so you can only modify arguments if you access the directly with an args() pointcut. This means enumerating all the join points because using reflection instead of proceed won't work.

You will need to use a dynamic proxy. Some AOP frameworks support this directly (I can't find an AspectJ enhancement) but you should be able to do it with AspectJ too. I haven't tried this myself (anyone else?) but this is what you need to do:
1. Define an interface that contains all the methods you want to intercept
2. Use declare parents ... : implements ... to add it to ULCProxy
3. Intercept the creation of instances of ULCProxy and return a Java dynamic proxy instead http://java.sun.com/j2se/1.5.0/docs/api/java/lang/reflect/Proxy.html.
4. Modify the String arguments in the invoke() method of the associated InvocationHandler (which is a bit like around advice)

Cheers

Matthew Webster
AOSD Project
Java Technology Centre, MP146
IBM Hursley Park, Winchester,  SO21 2JN, England
Telephone: +44 196 2816139 (external) 246139 (internal)
Email: Matthew Webster/UK/IBM @ IBMGB, matthew_webster@xxxxxxxxxx
http://w3.hursley.ibm.com/~websterm/



"Peter Koch" <Peter.Koch@xxxxxxxxxx>
Sent by: aspectj-users-bounces@xxxxxxxxxxx

27/11/2006 15:24

Please respond to
aspectj-users@xxxxxxxxxxx

To
<aspectj-users@xxxxxxxxxxx>
cc
Subject
[aspectj-users] around advice and modifying arguments





Hi!

I don't know how to solve the following issue
with AspectJ.

I'd like to have an advice which intercepts setter
method calls to any subclass of let's say the class ULCProxy.
I'd like then to modify then all the arguments type String
and proceed the method call with the modified arguments.

I started first with an easier example with intercepting
all calls to setter methods with exactly one String argument:

 pointcut setString(String string):
  execution(public void ULCProxy+.set*(String)) && args(string);

 void around(String string): setString(string)
 {
   if (string != null)
   {
     string = MacroExpandAspectJava.expand(string);
   }
   proceed(string);
 }

This works nice.


Now I'd like to do the same for all method calls with any
method signature but I don't know how to define this.
(e.g. setSomething(int i, boolean b, String s1, String s2))

I stopped thinking and tried instead the following approach using
a little bit of java reflection. This is my idea for the original
issue, but I don't think that it is very elegant (and of course it's
not performant and has some other upcomping problems):

 void around():  execution(public void ULCProxy+.set*(..))
 {
   Object[] args = thisJoinPoint.getArgs();
   for (int i = 0; i < args.length; i++)
   {
     if (args[i] instanceof String)
     {
       args[i] = MacroExpandAspectJava.expand((String) args[i]);
     }
   }

   //now, proceed(args); that's not ok...

   //instead: use reflection to proceed ?
   Object o = thisJoinPoint.getThis();
   Signature s = thisJoinPoint.getStaticPart().getSignature();
   String methodName = s.getName();
   Class[] paramTypes = new Class[args.length];
   for (int i = 0; i < paramTypes.length; i++)
   {
     paramTypes[i] = args[i].getClass();
   }
   try
   {
     o.getClass().getMethod(methodName, paramTypes).invoke(o, args);
   }
   catch (Exception e)
   {
     e.printStackTrace();
   }
 }


Thanks for any help solving my issue.

Best regards,
Peter Koch, ivyTeam
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users


Back to the top