[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] pertarget anomaly (was: bug with pertarget?)

Hi Ramnivas,

Thanks for the quick reply! It seems an interesting idea, so I modified my example in the following way:

public aspect taspect pertarget(set(* *.*) && !within(taspect)) {

    after() returning(Object o) : call(*.new(..)) && !within(taspect) {
	System.err.println("CONSTRUCTING - " + o);
    }

    after(Object o) : target(o) && set(* *.*) && !within(taspect) {
	System.err.println("SETTING - " + o);
    }
}

So, while this does now catch the field set, the constructor call is missed. I guess the reason is again that the target of a constructor call is strictly null. This seems unfortunate, since in this case there is no practical reason why this could not work (as everthing happens after the object is created).


Anyway, thanks again!

Dave

Ramnivas Laddad wrote:
The following may not help (since I do an not aware of the larger context of the problem you are trying to solve).

If you can live without advising the constructors (or advising them using a separate aspect), the following should work:

public aspect taspect pertarget(set(* *.*)&& !within(taspect)) {

... state that you are trying to associate with all objects on which set*() is called ...

   after(Object o) : target(o) && set(* *.*) && !within(taspect) {
       System.err.println("SETTING - " + o);
   }
}


=== Ramnivas Laddad, Author, AspectJ in Action http://ramnivas.com/blog


David Pearce wrote:

Hi all,

Well, i'm still chasing up a few things regarding use of pertarget. One thing I want to do is associate state with objects which are constructed and then monitor modifications to their fields. The following gives an example:

public aspect taspect pertarget(call(*.new(..)) && !within(taspect)) {

    after(Object o) : target(o) && call(*.new(..)) && !within(taspect) {
    System.err.println("CONSTRUCTING - " + o);
    }

    after(Object o) : target(o) && set(* *.*) && !within(taspect) {
    System.err.println("SETTING - " + o);
    }
}

public class test {
    public int testField;

    public static void main(String argv[]) {
    test t = new test();
    t.testField = 0;
    }
}



However, this does not work - neither "CONSTRUCTING - ..." nor "SETTING - ..." messages are printed. According to Ramnivas Laddad in his reply to my previous mail on this topic (see "re: bug with pertarget?"), the reason for this is:


This is due to implicit limiting of join points when using any of the per- associations.
For pertarget() associations, the advice application (or the scope of aspect) is
limited to where the join point’s target object matches the aspect’s associated object
(target object at call(test.new(..))).



So, the alternative implementation of the aspect is:

public aspect taspect perthis(execution(*.new(..)) && !within(taspect)) {

after(Object o) : target(o) && execution(*.new(..)) && !within(taspect) {
System.err.println("CONSTRUCTING - " + o);
}


    after(Object o) : this(o) && set(* *.*) && !within(taspect) {
    System.err.println("SETTING - " + o);
    }
}



However, this does not (of course) catch the setting of testField in test.main(). So, it seems I cannot express what I want using pertarget, although it is certainly possible to hand code it via inter-type declarations of the kind discussed in perious mails.


Anyway, I think that the first case above should work, since the pertarget specifier is really saying which objects the advice will work on. So, while the target of call(*.new(..)) is strictly null, it is clear which object it applies to and this object can be accessed via after() returning(Object o) mechanism.

Cheers,

Dave






_______________________________________________ aspectj-users mailing list aspectj-users@xxxxxxxxxxx http://dev.eclipse.org/mailman/listinfo/aspectj-users

_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
http://dev.eclipse.org/mailman/listinfo/aspectj-users