Skip to main content

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

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








Back to the top