Hi Ian -
> The problem is that the matching is done on the interface's throw
clause and not the implementation method's
Very interesting.
A given method actually has a number of signatures for matching purposes -
its own, and that of
anything it overrides. That way, when you target a method in a
supertype, it also targets the subtype.
However, for exceptions, that's not correct. If the method only
declares those exceptions, it does not
throw any others. I've confirmed that for method-execution, the
pointcuts match
the throws clauses for the overridden method. That looks like a
bug to me, which I took the
liberty of submitting:
(On the other hand, for method-call, you use the
declaring type and method regardless of the actual/implementing method or
its throws clause, because
that's not always determinable at compile-time. So for method-call
pointcuts on a method-call join
point using the interface-type reference, it would be correct to pick
out the join point since
the interface declares those exceptions, even if the implementing class
does not declare that
it throws them.)
I imagine the fix might be hard, since it involves saying, "Don't match
this part of the pointcut
signature unless using the actual join point signature, not any
inherited ones." To suggest
workarounds until a fix is available, I wonder if you can use
exclusion.
The programming guide section "Matching based on the throws clause"
describes how to exclude join points based on the exceptions they
throw.
AspectJ Programming Guide, Language Semantics Appendix, Pointcuts,
Matching,
Matching based on the throws clause:
The example there shows how to exclude join points if they throw an
exception:
pointcut doesNotThrowMathlike():
// each call to a method with a throws clause containing
no // exceptions with "Math" in its
name. call(* *(..) throws !*..*Math*);
Read the documentation on the difference between the following two:
# call(* *(..) throws !IOException) # call(* *(..) throws
(!IOException))
You might be able to use exclusion to get what you want for now, though if
we are matching
multiple-signatures that might be hard.
Thanks very much for bringing this up!
Wes
------------Original Message------------
From: "Conway. Fintan (IT Solutions)" <Fintan.Conway@xxxxxx>
To: aspectj-users@xxxxxxxxxxx
Date: Wed, Dec-7-2005 4:45 AM
Subject: RE: [aspectj-users] after() throwing matching on interface
throws clauses rather than method implementation
Hi
Ian,
Could you modify your 'after throwing()' to catch the Exceptions as
follows :
Catch Exception1 -
after throwing(Exception1 e1) throws Exception1 :
.....
Catch Exception2 -
after throwing(Exception2 e2) throws Exception2 :
.....
Catch Exception1 & Exception2 -
after throwing(Exception e) throws Exception :
.....
Will
this give you what you are looking for?
HTH,
Fintan
I want to add an
"after () throwing" pointcut to these methods that catch any exceptions, do
some logging and then throw an expected exception type. The problem is
that the matching is done on the interface's throw clause and not the
implementation method's.
I have:
- after ()
throwing (RuntimeException s) throws Exception1 : execution (* *.*(..)
throws Exception1 { ... }
- after () throwing (RuntimeException s) throws Exception2
: execution (* *.*(..) throws Exception2 { ... }
Unfortunately
the Exception1 clause matches against the method that throws Exception2.
This causes a compile error.
Example Source
with comments
------------------------------------------------------
public class
Exception1 extends Exception {} public class Exception2 extends Exception {}
public class
MyClass {
public
interface MyInterface { public Object MyMethod() throws
Exception1, Exception2; } private class
InnerClass1 implements MyInterface { public Object MyMethod()
throws Exception1 { return null; } } private
class InnerClass2 implements MyInterface { public Object
MyMethod() throws Exception2 { return
null;} } private class InnerClass3 implements
MyInterface { public Object MyMethod() throws Exception1,
Exception2 { return null;} } }
//
// First
attempt
//
public aspect MyAspect {
// This matches
against all 3 classes
// InnerClass2 causes an error
because this throws Exception1 but InnerClass2.MyMethod should only
throw Exception2 after () throwing (Exception e) throws
Exception1 : execution (* *.*(..) throws Exception1)
{}
// This
matches against all 3 classes
// InnerClass1 causes an error
because this throws Exception2 but InnerClass1.MyMethod should only
throw Exception1
after () throwing (Exception e) throws
Exception2 : execution (* *.*(..) throws Exception2)
{} }
//
// Second
attempt
//
public aspect MyAspect {
// This matches
against just InnerClass1. Good. after () throwing
(Exception e) throws Exception1 : execution (* *.*(..) throws
Exception1, !Exception2) {}
// This
matches against just InnerClass2. Good
after () throwing (Exception e) throws
Exception2 : execution (* *.*(..) throws Exception2, !Exception1)
{}
// This matches against
all 3 classes.
//
InnerClass1 causes an error because this throws Exception2 but
InnerClass1.MyMethod should only throw Exception1
// InnerClass2
causes an error because this throws Exception1 but InnerClass2.MyMethod
should only throw Exception2
// InnerClass3 is fine after ()
throwing (Exception e) throws Exception1, Exception2 : execution (*
*.*(..) throws Exception2, Exception1)
{} }
* ** *** ** * **
*** ** * ** *** ** * This email and any files transmitted with it are
confidential and intended solely for the use of the individual or entity
to whom they are addressed. Any views or opinions presented are solely
those of the author, and do not necessarily represent those of ESB. If
you have received this email in error please notify the sender.
Although ESB scans e-mail and attachments for viruses, it does not
guarantee that either are virus-free and accepts no liability for any
damage sustained as a result of viruses.
* ** *** ** * ** *** ** *
** *** ** *
_______________________________________________
aspectj-users mailing list aspectj-users@xxxxxxxxxxx https://dev.eclipse.org/mailman/listinfo/aspectj-users
|