Declare statements

The previous section on inter-type declarations covered the case of declare parents ... implements. The 1.5.0 release of AspectJ 5 will not support annotation style declarations for declare parents ... extends and declare soft (programs with these declarations would not in general be compilable by a regular Java 5 compiler, reducing the priority of their implementation). These may be supported in a future release.

Declare precedence and declare annotation will be supported. For declare precedence, use the @DeclarePrecedence annotation as in the following example:

     public aspect SystemArchitecture {
       declare precedence : Security*, TransactionSupport, Persistence;

       // ...
     }

     can be written as:

     @Aspect
     @DeclarePrecedence("Security*,org.xyz.TransactionSupport,org.xyz.Persistence")
     public class SystemArchitecture {

       // ...
     }
         

Declare annotation is supported via annotations on a dummy type member. If the Target specification of the annotation allows it, use a field, otherwise declare a member of the type required by the Target. For example:

     public aspect DeclareAnnotationExamples {
       declare annotation : org.xyz.model..* : @BusinessDomain;

       declare annotation : public * BankAccount+.*(..) : @Secured(role="supervisor");

       declare anotation : * DAO+.* : @Persisted;

     }

     can be written as...

     @Aspect
     public class DeclareAnnotationExamples {

       @DeclareAnnotation("org.xyz.model..*)
       @BusinessDomain Object modelClass;

       // this example assumes that the @Secured annotation has a Target
       // annotation with value ElementType.METHOD
       @DeclareAnnotation("public * org.xyz.banking.BankAccount+.*(..)")
       @Secured(role="supervisor) void bankAccountMethod();

       @DeclareAnnotation("* DAO+.*")
       @Persisted Object daoFields;
     }
         

We also support annotation style declarations for declare warning and declare error - any corresponding warnings and errors will be emitted at weave time, not when the aspects containing the declarations are compiled. (This is the same behaviour as when using declare warning or error with the code style). Declare warning and error declarations are made by annotating a string constant whose value is the message to be issued.

Note that the String must be a constant and not the result of the invocation of a static method for example.

       declare warning : call(* javax.sql..*(..)) && !within(org.xyz.daos..*)
                       : "Only DAOs should be calling JDBC.";

       declare error : execution(* IFoo+.*(..)) && !within(org.foo..*)
                     : "Only foo types can implement IFoo";

       can be written as...

       @DeclareWarning("call(* javax.sql..*(..)) && !within(org.xyz.daos..*)")
       static final String aMessage = "Only DAOs should be calling JDBC.";

       @DeclareError("execution(* IFoo+.*(..)) && !within(org.foo..*)")
       static final String badIFooImplementors = "Only foo types can implement IFoo";

       // the following is not valid since the message is not a String constant
       @DeclareError("execution(* IFoo+.*(..)) && !within(org.foo..*)")
       static final String badIFooImplementorsCorrupted = getMessage();
       static String getMessage() {
           return "Only foo types can implement IFoo " + System.currentTimeMillis();
       }