Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Use Cases for Changing target and this in proceed

Hi -

> these seem to be examples of changing the 
> target object.

Let's say lots of clients use a registry.

If I control (only) the Registry class, then I can change how the 
"register(Parm p, ..)" method executes, selecting a strategy based on
whether the moon is full and p is an earth sign.  This advice on
method-execution Registry.register(Parm p,..) means I don't have to
reweave every Registry client to implement my astrological strategy.
(Normally arguments from code-the-compiler-controls are suspect, but
there are semantic equivalents where you'd rather advise execution.)

> I'm trying to find a use case where it makes sense to 
> cause subsequent advice to think that the original client was different 

"advice to think...": changing any parameter, this, or target introduces
a potential coherance problem, where other users "expect" something to 
happen as a consequence of proceeding with the original object or value.  
If you change these, it's your responsibility to manage the coherance issues.

The issues do present differently for parameters, target, and this.  E.g., 
for method-call join points, method dispatch happens after proceed(..)
whereas in execution join points method-dispatch has happened before any 
advice is executed.  Changing target in proceed(..) of around advice on a 
method-call join point can change the method executed.  Conversely, changing
"this" using a subclass instance in proceed(..) in around advice on method
execution does not change the method executed.  Indeed, the superclass 
implementation of the method is run even if the subclass overrided that 
implementation. (see code below).

> But I wonder if a language might use a different form for 
> proceed where the arguments matched those of the original join point 
> instead of the parameters of the surrounding advice.

Then one couldn't write one piece of around advice for different {kinds 
of} join points.

These are really good questions.  Most OO programmers don't put "this"
on par with some parameter value, and AOP programmers might not consider
carefully things like method dispatch and precedence when considering
the potential interference.  At the very least, replacing "this" raises
issues many developers haven't considered before, and uncovers some of
the complexity in the Java language.  This is another place where I
wish Java supported "const".

Wes

The following code shows:
- replacing "this" in around advice on method execution with a subclass
  that overrides the method will *not* result in the overriding subclass
  method being called.  Method dispatch happens before method execution.

- more-precedent after advice is not affected when less-precedent after
  advice changes the "this" parameter.  Thus, it is not simply that the
  value is changed for all subsequent processing, but only for less-
  precedent advice and the original join point.

----- output
Replacing C with D
in C(): D@cac268
after running, this is C@1cde100

----- code - Over.java

public class Over {
  public static void main(String[] args) { new C().run(); }
}
class C {
  public void run() { System.out.println("in C(): " + this); }
}
class D extends C {
  public void run() { System.out.println("in D()" + this); }
}
aspect A {
  pointcut cRunExecution(C c) :
        execution(void C.run()) && this(c) && within(C) ;
  void around(C c) : cRunExecution(c) {
        System.out.println("Replacing C with D");
       proceed(new D());
  }
}
aspect B {
  declare precedence : B, A;
  after (C c) returning : A.cRunExecution(c) {
        System.out.println("after running, this is " + c);
  }
}


> ------------Original Message------------
> From: Curtis Clifton <curt.clifton@xxxxxxx>
> To: aspectj-users@xxxxxxxxxxx
> Date: Mon, Dec-13-2004 2:31 PM
> Subject: Re: [aspectj-users] Use Cases for Changing target and this in proceed
>
> Wes,
> 
> Thanks for the quick reply...
> 
> On Dec 13, 2004, at 3:31 PM, Wes Isberg wrote:
> 
> >> However, I haven't been able to come up with a
> >> realistic use case for changing the "this" object.
> >
> > One use is to apply the strategy pattern to a template method.
> > Another would be to cache a local copy of a remote object; a
> > variant of this would be to batch updates.  The basic idea is
> > that there are policies with different behavior or state that
> > one might want to apply using proxy-like behavior in situations
> > where you can't manage the references held by the client.
> 
> Perhaps I'm being dense, but these seem to be examples of changing the 
> target object.  I'm trying to find a use case where it makes sense to 
> cause subsequent advice to think that the original client was different 
> 
> (neglecting execution point cuts where target and this are confounded).
> 
> > Do you think this is a case where AspectJ is too powerful? Would the 
> > language be simpler or more complex if you couldn't
> > replace this or target?
> 
> My intuition is that eliminating the ability to change the target 
> object would sacrifice too much power.  It is fairly easy to come up 
> with use cases where it is helpful to change the target object.  
> However, I don't yet understand why one would want to change the "this" 
> 
> object.
> 
> (Warning, the rest of this message gets into speculative language 
> design questions.  And, lest you think I'm an interloper, please note 
> that I am not advocating for changes to AspectJ.  I'm just pondering 
> alternative design decisions.)
> 
> Omitting the ability to change this or target without making any other 
> changes to the language would seem to make the language more complex: 
> certain parameters to proceed would follow different rules than other 
> parameters.  But I wonder if a language might use a different form for 
> proceed where the arguments matched those of the original join point 
> instead of the parameters of the surrounding advice.  The target object 
> 
> could be changed by prefixing the proceed with "target_expression."  
> For example:
> 
> void around(A tar, int arg) : call(void m(int)) && target(tar) && 
> args(arg) {
> 	new A().proceed(arg * 2);  // equivalent to current AspectJ's 
> proceed(new A(), arg)
> }
> 
> This would match the intuition that a proceed is like the original 
> triggering event for the join point, but with new data.  It also 
> eliminates the confusion that can arise when two different advice 
> parameters are bound to the same join point data and the proceed 
> changes just one of them, as in the following AspectJ code:
> 
> void around(A tar1, A tar2) : call(void m()) && target(tar1) && 
> target(tar2) {
> 	proceed(tar1, new A());  // the actual target is the new A, or 
> generally whichever is right-most
> }
> 
> In the design I'm pondering that last proceed would be written "new 
> A().proceed()", eliminating any confusion about the actual target.
> 
> There are a variety of issues with the design I'm pondering, including 
> 1) confounding the proceed special form with a call to a method named 
> proceed, 2) determining the type for proceed when the pointcut doesn't 
> yield a unique type for the originally called method, and 3) not being 
> able to change the _this_ object.
> 
> I'm trying to understand how big the loss is in issue 3.
> 
> Best,
> 
> Curt
> 
> ----------------------------------
> Curtis Clifton, PhD Candidate
> Dept. of Computer Science, Iowa State University
> http://www.cs.iastate.edu/~cclifton
> 
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> http://dev.eclipse.org/mailman/listinfo/aspectj-users
> 




Back to the top