Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
RE: interecepting all calls -- was Re: [aspectj-users] interecepting of all calls and forwarding them, aspect methods and private fields

When we added declare warn and declare error, we chose the syntax we
did in part to allow future support for this kind of delegation.

The idea was that someone could add a language feature of the form:


  declare delegate Foo Stopped mock;

Which would do something like:

 define in the class Stopped all the methods in the Foo
 interface; the methods should forward to mock.

Of course this simple design doesn't work, because it means the aspect
knows the name of the field the delegatee is stored in.  We didn't
have time to figure out a good design for this feature then.

But by adding the declare xxx syntax to the language the idea was
that it created syntactic space for people to later add a variety
of generative extensions like declare delegate.

Maybe now that AspectJ development is moving to truly open source
this is something someone could do.

The first thing to do would be to come up with half-a-dozen concrete
examples and discuss them on this list.  That would give the original
language designers (and others) a chance to weigh in on possible hidden
problems before the actual implementation started.

> -----Original Message-----
> From: aspectj-users-admin@xxxxxxxxxxx 
> [mailto:aspectj-users-admin@xxxxxxxxxxx] On Behalf Of Wes Isberg
> Sent: Thursday, February 27, 2003 10:51 AM
> To: aspectj-users@xxxxxxxxxxx
> Subject: interecepting all calls -- was Re: [aspectj-users] 
> interecepting of all calls and forwarding them, aspect 
> methods and private fields
> 
> 
> (Splitting the emails - 1 topic per email, please.)
> 
> "Wojciech (Voytek) Dzidek" wrote:
> > 
> > Question 1:
> > 
> > Let's say I have two classes: Stopped and StoppedStub. 
> During testing I want all calls to Stopped
> > be forwarded to StoppedStub. 
> 
> Forwarding can be done with reflection based on the signature 
> available
> from thisJoinPoint for method-call join points.  (*shudder*)
> 
> But forward to which instance?  A different one for each call?
> 
> Aside from forwarding, you can also replace the executing object with 
> your mock object.  But when?  Likely on construction or relevant
> assignment, to preserve the identity of the mock object across the
> relevant invocations.  But since there is no join point for local 
> variable assignments, this is sometimes not possible.
> 
> There's also the question of maintenance.  What happens if methods 
> are added to the component under test, but not the mock?
> 
> Below is some code that replaces with a mock for each call.  
> It assumes
> interface I defines the contract supported by both the component
> under test and the mock object.
> 
> Here's the result:
> ----------- without the aspect -- same instance for two calls
> B@126b249.a()
> B@126b249.b()
> ----------- with the aspect -- different mock for two calls
> Mock@182f0db.a()
> Mock@192d342.b()
> ----------- 
> 
> I'd be interested to see a code example with advice that replaced 
> the object after it was constructed.
> 
> Wes
> 
> ----------- Replace.java
> 
> public class Replace {
>     public static void main (String[] args) {
>         I i = new B();
>         i.a();   // two different calls to same instance
>         i.b();
>     } 
>     static void log (String m) { System.out.println(m); }
> }
> 
> interface I {
>     void a();
>     void b();
> }
> 
> class B implements I {
>     public void a() { Replace.log(this + ".a()"); }
>     public void b() { Replace.log(this + ".b()"); }
> }
> 
> class Mock implements I {
>     public void a() { Replace.log(this + ".a()"); }
>     public void b() { Replace.log(this + ".b()"); }
> }
> 
> aspect A {
>     pointcut testing() :  
>         cflow(execution(static void Replace.main(..))) && !within(A);
> 
>     /** replace B with new Mock before every method-call to B 
> as I */   
>     Object around(I targ) : testing() &&
>         target(targ) && target(B) && call(* I.*(..)) {
>         return proceed(new Mock());
>     }
> }
> -----------
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> http://dev.eclipse.org/mailman/listinfo/aspectj-users
> 



Back to the top