Skip to main content

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

I've discussed this with the AJDT team and we've concluded that this is an AspectJ feature, so would like to discuss here.
 
This is about "after throwing" pointcuts on interfaces where the implementing classes have more restrictive throws clauses than the interface.
The AJDT team think this functionality is desirable, but I cant understand the rationale. Another confusion is that when I'm building in Maven (using aspectjrt 1.5.0_M5), it calls ant's iajc task. It doesnt report any problems. But it does report problems if you call the compiler directly. Perhaps for some reason even though I'm specifying this version in my maven project xml, ant may be using a different version.
 
 
Consider an interface that has a method that declares that it can throw exception Exception1 or Exception2.
There are three different classes that implement this interface. One can throw both exceptions, one can only throw Exception1 and the other can only throw Exception2.
 
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) {}
}
 


--------------------------------------------------------------------------------
The information contained herein is confidential and is intended solely for the
addressee. Access by any other party is unauthorised without the express
written permission of the sender. If you are not the intended recipient, please
contact the sender either via the company switchboard on +44 (0)20 7623 8000, or
via e-mail return. If you have received this e-mail in error or wish to read our
e-mail disclaimer statement and monitoring policy, please refer to
http://www.drkw.com/disc/email/ or contact the sender. 3167
--------------------------------------------------------------------------------

Back to the top