Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
RE: [aspectj-users] after advice with overridden methods

sorry for this flood of letters, but i go crazy over this advice stuff.
i can not think of anything else then a compiler bug, but i know no ways
to check this...

i have an advice like this:

after(Screen screen):
	call(void Component.init()) && target(screen)
{
	if (log.isDebugEnabled())
		log.debug("Calling createContent of [" + screen + "] due
to [" + thisJoinPoint + "]", new Throwable());
	
	screen.createContent();
}

Screen indirectly extends Component, init() is an overridden chain of
functions with super.init() calls, Screen.init() runs only once
according to the log. but the advice runs three times on the same
instance?! this instance is an subclass of Screen.

in the log each three calls have the exact same stack trace... according
to my knowledge if Screen.init() runs once then this must be either a
bug in the compiler or in my brain.

i've just tried with around, same result.

am i missing something obvious?

is there a way i can debug this?

all feedback is appretiated,

101


:: :: I think the aspect is behaving correctly.
:: :: 
:: :: Programming Guide, Semantics appendix:
:: :: 
:: ::    At a method execution join point, the signature [is]
:: ::    a method signature whose qualifying type is the
:: ::    declaring type of the method.
:: :: 
:: :: So a method-execution pointcut will match not only the 
:: :: declaring type, but also any implementation of that method 
:: :: (i.e., any overriding methods).
:: :: 
:: :: Rather than cflow, try
:: :: 
:: ::     execution(void init()) && within(A)
:: :: 
:: :: This is staticly-determinable (read: more efficient).
:: :: 
:: :: You might also prefer to use call(..).
:: 
:: 
:: i'm still having trouble...
:: 
:: - i can't use call() because the method is called from a 
:: different jar (it's Echo's void Component.init()). i would 
:: not use injars if possible.
:: - using within(A) is problematic because A varies over 
:: several classes. and if i forget to list one of my 
:: subclasses then it silently won't work for that class. i 
:: hate such error-prone solutions. (not to mention that there 
:: would be several such within(A)'s)
:: 
:: for the big picture: i subclass various components that come 
:: from a Echo's jar, and in a mixin-like aspect i declare an 
:: after advice on a method named init() (gets called by the 
:: framework when the component is added). i would like to have 
:: an  advice run once, and only once for all of my component 
:: subclasses on which the aspect is applied. but i subclass my 
:: components further, so simply by execution(void
:: Component+.init()) the advice runs as many times as i 
:: subclass my first
:: class in the inheritance tree.
:: 
:: having a special execution() and this() combined pointcut 
:: would help. in fact two of them, one that catches the most 
:: specific version of the method, and one that catches the 
:: most general one (from those that are visible for the weaver 
:: of course).
:: 
:: btw, i couldn't solve it with cflow() variants either, but 
:: it could be my limitation. in some cases, that i can't 
:: identify, the advice didn't run.
:: 
:: any ideas?
:: 
:: - 101
:: 
:: 
:: 
:: :: 
:: :: Wes
:: :: 
:: :: Lendvai Attila wrote:
:: :: > hello all,
:: :: > 
:: :: > if i have the following setup: (three classes, extending 
:: :: each other 
:: :: > and overriding a function)
:: :: > 
:: :: > class A
:: :: > {
:: :: >         void init()
:: :: >         {
:: :: >                 System.out.println("A.init()");
:: :: >         }
:: :: > }
:: :: > 
:: :: > class B extends A
:: :: > {
:: :: >         void init()
:: :: >         {
:: :: >                 System.out.println("B.init()");
:: :: >                
:: :: >                 super.init();
:: :: >         }
:: :: > }
:: :: > 
:: :: > class C extends B
:: :: > {
:: :: >         void init()
:: :: >         {
:: :: >                 System.out.println("C.init()");
:: :: >                
:: :: >                 super.init();
:: :: >         }
:: :: > }
:: :: > 
:: :: > private static aspect Chain {
:: :: >         pointcut f() : execution(void A.init());
:: :: > 
:: :: >         after(A a) : f() && this(a)
:: :: >         {
:: :: >                 System.out.println("After init, this [" 
:: + a + "] 
:: :: > thisJoinPoint [" + thisJoinPoint + "]");
:: :: >         }
:: :: > }
:: :: > 
:: :: > 
:: :: > in the main:
:: :: > 
:: :: > C c = new C();
:: :: > c.init();
:: :: > 
:: :: > output:
:: :: > 
:: :: > C.init()
:: :: > B.init()
:: :: > A.init()
:: :: > After init, this [com.netvisor.nvsr.client.Factorial$C@1fc2fb]
:: :: > thisJoinPoint [execution(void 
:: :: > com.netvisor.nvsr.client.Factorial.A.init())]
:: :: > After init, this [com.netvisor.nvsr.client.Factorial$C@1fc2fb]
:: :: > thisJoinPoint [execution(void 
:: :: > com.netvisor.nvsr.client.Factorial.B.init())]
:: :: > After init, this [com.netvisor.nvsr.client.Factorial$C@1fc2fb]
:: :: > thisJoinPoint [execution(void 
:: :: > com.netvisor.nvsr.client.Factorial.C.init())]
:: :: > 
:: :: > 
:: :: > 
:: :: > shouldn't be there only one After init message? note that it's 
:: :: > A.init(), not A+.init() in the pointcut! changing to A+ 
:: :: does not have 
:: :: > any effect on the output.
:: :: > 
:: :: > i can workaround the problem by adding && 
:: !cflowbelow(f()) to the 
:: :: > advice, but in a much more complex scenario it does not 
:: :: get called for 
:: :: > all the object i would like to... :(
:: :: > 
:: :: > so my question is: is everything ok with the above output?
:: :: > 
:: :: > thanks in advance,
:: :: > 
:: :: > 101
:: :: > 
:: :: >  
:: :: > 
:: :: >  
:: :: > 
:: :: > 
:: :: 
:: :: _______________________________________________
:: :: 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
:: 
:: 


Back to the top