|
CS 683 Emerging Technologies Spring Semester, 2003 AspectJ Syntax 2 |
|
|---|---|---|
|
© 2003, All Rights Reserved, SDSU & Roger Whitney San Diego State University -- This page last updated 30-Jan-03 |
AspectJ Syntax 2
Viewing Aspect Source Code
ajc -preprocess @Hello.lst
public class Hello {
public Hello() {
this(5);
System.out.println("Hello()");
}
public Hello(int x) {
System.out.println("Hello(" + x + ")");
}
public static void main(String[] args ) {
new Hello();
}
}
public aspect HelloAspect {
before() : call( Hello.new(..) ) {
System.out.println( "call-before");
}
before() : execution(Hello.new(..)) {
System.out.println( "execution-before");
}
}
Generated
Hello.java
/* Generated by AspectJ version 1.0.6 */
public class Hello {
public Hello() {
this(5);
HelloAspect.aspectInstance.before1$ajc();
;
System.out.println("Hello()");
}
public Hello(int x) {
super();
HelloAspect.aspectInstance.before1$ajc();
System.out.println("Hello(" + x + ")");
}
public static void main(String[] args) {
Hello.new$constructor_call();
}
private static Hello new$constructor_call() {
HelloAspect.aspectInstance.before0$ajc();
return new Hello();
}
}
Generated
HelloAspect
/* Generated by AspectJ version 1.0.6 */
public class HelloAspect {
public final void before0$ajc() {
System.out.println("call-before");
}
public final void before1$ajc() {
System.out.println("execution-before");
}
public HelloAspect() {
super();
}
public static HelloAspect aspectInstance;
public static HelloAspect aspectOf() {
return HelloAspect.aspectInstance;
}
public static boolean hasAspect() {
return HelloAspect.aspectInstance != null;
}
static {
HelloAspect.aspectInstance = new HelloAspect();
}
}
cflow
cflow(Pointcut)
Example public class Hello { public void c() { System.out.println("C"); } public void b() { System.out.println("B"); c(); } public void a() { System.out.println( "A"); b(); } public static void main(String[] args ) { Hello test = new Hello(); test.c(); test.b(); test.a(); } }
Same behavior when referring to b()
public aspect HelloAspect { before() : call( * b() ) && withincode( * a() ) { System.out.println( "call-within"); } before() : call( * b() ) && cflow( call(* a()) ) { System.out.println( "call-cflow"); } }Output
C
B
C
A
call-within
call-cflow
B
C
Different behavior when referring to c()
public aspect HelloAspect { before() : call( * c() ) && withincode( * a() ) { System.out.println( "call-within"); } before() : call( * c() ) && cflow( call(* a()) ) { System.out.println( "call-cflow"); } }
Output
C
B
C
A
B
call-cflow
C
Recursive calls
An example to show how to pick off the start and tail of recursion
public class Hello { public void a(int repeats) { System.out.println( "A" + repeats); if (repeats > 0) a( repeats - 1); } public static void main(String[] args ) { Hello test = new Hello(); test.a(4); } }
The Aspect
public aspect HelloAspect { before() : call( * a(int) ) && withincode( * a(int) ) { System.out.println( "call-within"); } before() : call( * a(int) ) && !cflowbelow( call(* a(int)) ) { System.out.println( "call-cflow"); } }
Output call-cflow
A4
call-within
A3
call-within
A2
call-within
A1
call-within
A0
Some More on Matching
Boxing
public class Hello { public void a(int repeats) { System.out.println( "A" + repeats); } public static void main(String[] args ) { Hello test = new Hello(); test.a(4); } }
public aspect HelloAspect { before(Object boxed) : call( * a(int) ) && args(boxed) { System.out.println( "Match " + boxed); } }Output
Match 4
A4
Wildcards Again
* matches zero or more characters except for “.”
.. matches any sequence of characters that start & end with a ‘.’
target(java.util.*)
Subtype Patterns
+
public class Hello {
public Hello() {
System.out.println("Hello Contructor" );
}
}
public class Child extends Hello {
public Child() {
System.out.println("Child Contructor" );
}
}
Examples
public aspect HelloAspect { before() : call( Hello.new() ) { System.out.println( "Match "); } }
new Hello() Produces Match
Hello Constructor
new Child() Produces Hello Constructor
Child Constructor
public aspect HelloAspect { before() : call( Hello+.new() ) { System.out.println( "Match "); } }
new Hello() Produces Match
Hello Constructor
new Child() Produces Match
Hello Constructor
Child Constructor
public aspect HelloAspect { before() : call( (Hello+ && ! Hello).new() ) { System.out.println( "Match "); } }
new Hello() Produces Hello Constructor
new Child() Produces Match
Hello Constructor
Child Constructor
After Returning
after() returning()
public class Hello {
int increase(int value) {
return value + 1;
}
public static void main(String[] args ) {
Hello test = new Hello();
test.increase(5);
}
}
public aspect HelloAspect {
after() returning() : call( int increase(int) ) {
System.out.println( "No parameters ");
}
after() returning(Object returnBoxed) : call( int increase(int) ) {
System.out.println( "Returned " + returnBoxed);
}
after(int arg) returning(int returned) : call( int increase(int) ) && args(arg) {
System.out.println( "In " + arg + " Out " + returned);
}
}
Exceptions
Catching & After
import java.io.IOException; public class Hello { int a(int value) throws IOException { if (value == 3) throw new IOException(); System.out.println( "In a"); return value + 1; } public static void main(String[] args ) { Hello test = new Hello(); try { test.a( Integer.parseInt(args[0]) ); } catch (IOException example) { System.out.println( "In Handler"); } } }
The Aspects
import java.io.IOException;
public aspect HelloAspect { after() : call( int a(int) ) { System.out.println( "After "); } after() returning : call( int a(int) ) { System.out.println( "returning "); } after() throwing : call( int a(int) ) { System.out.println( "throwing "); } after() :handler(IOException) { System.out.println("After handler"); } }
Running java Hello 4 In a
After
Returning
Running java Hello 3 After
throwing
In Handler
After handler
Warning about not importing Exception
The following aspect does compile and will run, but not the way one thinks
public aspect HelloAspect { after() : call( int a(int) ) { System.out.println( "After "); } after() returning : call( int a(int) ) { System.out.println( "returning "); } after() throwing : call( int a(int) ) { System.out.println( "throwing "); } after() :handler(IOException) { System.out.println("After handler"); } }
Running java Hello 3 After
throwing
In Handler
Throwing Checked Exceptions in Advice
Advice must explicitly declare if it throws an exception
import java.io.IOException; public aspect HelloAspect { before() throws IOException : call( int a(int)) { throw new IOException(); } after() throws IOException : call( int a(int)) { throw new IOException(); } after() throwing(IOException e) throws IOException : call( int a(int)) { throw new IOException(); } }
Restrictions on Throwing Exceptions
Exceptions a join point in AspectJ may throw are:
Illegal Example
This advice will not compile
public class Hello { void b() { System.out.println("In b"); } }
import java.io.IOException; public aspect HelloAspect { before() throws IOException : call( void b()) { throw new IOException(); } }
Throwing Uncheck Exceptions in Advice
Unchecked exceptions can be thrown in advice
public class Hello { void b() { System.out.println("In b"); } public static void main(String[] args ) { Hello test = new Hello(); test.b(); } }
public aspect HelloAspect { before() : call( void b()) { throw new ArithmeticException (); } }
Warnings & Errors
Can specify that a join point should not be reached
Compiler will signal the problem
Forms:
declare error : Pointcut : String
declare warning: Pointcut : StringExample public class Hello { void b() { System.out.println("In b"); } public static void main(String[] args ) { Hello test = new Hello(); test.b(); } } public aspect HelloAspect { declare error : call( void b()) : "Error string displayed by compiler"; }
Aspect Extension
An aspect may
public abstract aspect ParentAspect {
pointcut methodB() : call(* b(..) );
}
aspect ChildAspect extends ParentAspect {
before() : methodB() {
System.out.println(" Advise " );
}
}
Aspect
Extending a Class
public class Hello {
void b() {
System.out.println("In b");
}
}
public aspect HelloAspect extends Hello {
before() : call(* foo() ) {
b();
}
}
Aspect
State & Methods
Aspects
can have state and methods
Aspects
normally are created as singletons
AspectName.aspectOf()
returns the singleton
public aspect HelloAspect {
private int callCount = 0;
public int getCount() {
return callCount;
}
public static void main(String[] arguments ) {
HelloAspect aspect = HelloAspect.aspectOf();
System.out.println( "Count is " + aspect.getCount() );
}
before() : call(* *(..) ) {
callCount++;
}
}
Result
of running java HelloAspect
Count
is 3
Copyright ©, All rights reserved.
2003 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.
Previous   
visitors since 30-Jan-03
   Next