Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
RE: [aspectj-users] after() throwing matching on interface throws clauses rather than method implementation

Title: Message
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
-----Original Message-----
From: aspectj-users-bounces@xxxxxxxxxxx [mailto:aspectj-users-bounces@xxxxxxxxxxx] On Behalf Of Orford, Ian
Sent: 07 December 2005 12:04
To: 'aspectj-users@xxxxxxxxxxx'
Subject: [aspectj-users] after() throwing matching on interface throws clauses rather than method implementation

 
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

Back to the top