Community
Participate
Working Groups
The programming guide says, It is an error to try to put after returning advice on a join point that does not return the correct type. For example, after() returning (byte b): call(int String.length()) { // this is an error } is not allowed. But if no return value is exposed, or the exposed return value is typed to Object, then it may be applied to any join point. The compiler emits no such error. See tests/bugs/IncompatibleAfterReturningTypeCE.java Perhaps this is the time/place to confirm and (plan to) document the correct and/or actual behavior. Here's what I think (users would think) is correct for the form after() returning (Type t) : pc() { ... } 1) When a join point picked out by pc() is declared to return Type or a subtype of Type, then the advice should run at the join point, even if the actual value returned is null. This differs from the case of args(..), et al. 2) Otherwise, when the join point is not declared to return a supertype of Type, the compiler should emit an error stating that the join point is declared to return a type incompatible with Type. 3) Otherwise, when the join point is declared to return a supertype of Type, there are two options: (a) The advice should run if the actual return value is an instance of Type. This implicitly adds to the pointcut a dynamic test for the actual value of the result. If possible, we should write XLint messages for each such join point shadow. (b) The compiler should emit an error, since (a) violates the principle that (only) pointcuts pick out join points and might be confusing to users in cases where the return value is null. The user can fix the code by using a common supertype and then doing an instanceof check.
I'm moving this to be a doc bug after discussing the issue with Erik. We decided in 1.1.1 to make the matching rules for after returning(C c) to be based on instanceof matching in the same way that after throwing is. We decided that having these two constructs behave in a parallel way was more important than the additional benefits of static type checking people would get otherwise. There should probably be a Xlint warning to let people know when after returning advice either might not or definately will not run at a particular join point shadow based on the additional matching done by the type in returning.
Oops, I should have said "we decided in the design of 1.1" rather than "1.1.1". This decision was made about a year ago when we first implemented bytecode weaving.
After exploring this bug I've written a comprehensive test case tests/new/AfterReturningParamMatching.java however, this test case exposed a compiler blowup when after() returning(byte b) is applied to an Object returning jp. I've rewritten the semantics document to reflect the correct (instanceof-like) semantics, checked the above test case into ajcTestsFailing.xml, moved this bug back to the compiler and raised its severity to P2. I'm still owner, and will fix it when I get the chance. -erik
The proper semantics for after returning parameter exposure should now be implemented, and the test case has been moved into ajcTests.