AspectJ - Java based AOP System

45
AspectJ - Java based AOP System

description

AspectJ - Java based AOP System. AspectJ - basic features. Compatible extension to Java: Upward Compatibility - all legal Java programs are legal AspectJ programs Platform Compatibility - all legal AspectJ programs run on all standard Java VM - PowerPoint PPT Presentation

Transcript of AspectJ - Java based AOP System

Page 1: AspectJ - Java based AOP System

AspectJ - Java based AOP System

Page 2: AspectJ - Java based AOP System

AspectJ - basic features• Compatible extension to Java:

– Upward Compatibility - all legal Java programs are legal AspectJ programs

– Platform Compatibility - all legal AspectJ programs run on all standard Java VM

– Tool Compatibility - existing tools can be extended to support AspectJ in a natural way: IDEs, documentation and design tools

– Programmer Compatibility - Programming with AspectJ must feel like a natural extension to programming with Java

Page 3: AspectJ - Java based AOP System

AspectJ - basic features (contd.)• AspectJ program structure:

– Classes - like in Java– Aspects - for concerns that crosscut class

structure

• AspectJ crosscutting implementation– Dynamic - define additional implementation to

run at certain point of program execution– Static - define new operation on existing types

(introduction)

Page 4: AspectJ - Java based AOP System

AspectJ - language overview

• Basic concepts:– Joinpoint - certain points in a program’s

execution (for example - a call to a class’ method

– Pointcut - Program constructs to designate joinpoints and to collect specific context at these points

– Advice - Code that runs upon meeting certain conditions

– Aspect - class like crosscutting unit, where advice and pointcuts form weaving rules

Page 5: AspectJ - Java based AOP System

Joinpoints• certain points in a program’s execution

– have context associated with them (for example a method call joinpoint can have the target object as a part of the context

– in AspectJ, available joinpoints are limited to the following:

• Method call and execution

• Constructor call and execution

• Read/Write access to field

• Exception handler execution

• Object and class Initialization execution

Page 6: AspectJ - Java based AOP System

Pointcut designators• Program constructs to designate

Joinpoints

• set of Joinpoints and (optionally) some values from their execution context

• AspectJ provides primitive pointcut designators which can be used to compose named/anonymous user defined pointcuts

Page 7: AspectJ - Java based AOP System

Pointcut designators (contd.)• primitive pointcut designators:

– calls(signature) / receptions(signature) / executions(signature) - matches call/reception/execution join points at which the method/constructor called matches signature; method signature: ResultTypeName RecvrTypeName.meth_id (params) constructor signature: NewObjectTypeName.new (params)

– gets(signature) / gets(signature) [val] / sets(signature) / sets(signature) [oldVal] / sets(signature) [oldVal] [newVal] - matches get / set join points where the field accessed matches signature; field signature: FieldTypeName ObjectTypeName.field_id

Page 8: AspectJ - Java based AOP System

Pointcut designators (contd.)• primitive pointcut designators (contd):

– handles(ThrowableType) - matches exception handler execution join point of the specified type

– instanceof(CurrentlyExecutingObjectType) - “this” is of specified type

– within(ClassName) / withincode(signature) -the executing code is contained within ClassName / within the specified method

– cflow(pointcut_designator) - for example <cflow (call (* MyClass.myMethod (..))> - all joint points in control flow of call to the method

Page 9: AspectJ - Java based AOP System

Pointcut designators (contd.)• primitive pointcut designators (contd):

context collecting pointcuts:– this(object) - all the join points where “this” is

the object specified– target(object) - the method is called on

specified object– args(arg1, ..) - the join points where the

arguments are as specified– named / unnamed pointcuts (like named /

unnamed classes)– use ||, &&, !, .., *, + to compose pointcuts

Page 10: AspectJ - Java based AOP System

Advices• Associate code with a specific pointcut

• Advice types available: before, after (after returning / after throwing), around

• the context is passed to advice by the pointcut

• example: pointcut move (Line l):

receptions (void l.MoveXY (int, int)); after (Line l): move (l) {/*print msg*/}

Page 11: AspectJ - Java based AOP System

Advices (contd.)• Order of advice execution:

– any around advise (most specific first); the invocation of proceed () invokes next most specific around advise

– any before advice, most specific first

– the computation itself

– all after advice, less specific first

– return value from step (3) is returned to the innermost call to proceed () and that piece of around advice continues running

– when the innermost around advice finishes, the surrounding around advice continues running

– once the outermost piece of around advice returns, control continues back from the join point

Page 12: AspectJ - Java based AOP System

Advices (contd.)• Aspect precedence (for two pieces of advice a1,a2

defined in aspects A1,A2 respectively)– if A1 = A2, the advice that appears first in the

aspect’s declaration body is more specific– A1 extends A2 --> a1 is more specific– declaration of A1 includes a dominates

modifier that mentions A2 --> a1 is more specific than a2

Page 13: AspectJ - Java based AOP System

Aspects• Modular units of crosscutting

implementation

• declaration - similar to class declaration

• include pointcut declarations, advice declarations and declarations permitted in class declaration

• aspect inheritance, abstract aspects are supported

Page 14: AspectJ - Java based AOP System

Example1 - thread pooling

• Thread pooling - more effective and resource saving approach to thread managenment

• AOP implementation in a modular fashion - source code need not be modified

• original code - simple multithreaded Server

Page 15: AspectJ - Java based AOP System

// UppercaseServer.javaimport java.io.*;import java.net.*;

public class UppercaseServer { public static void main(String[] args) throws Exception { if (args.length != 1) { System.out.println("Usage: java UppercaseServer "); System.exit(1); }

int portNum = Integer.parseInt(args[0]); ServerSocket serverSocket = new ServerSocket(portNum);

while(true) { Socket requestSocket = serverSocket.accept(); Thread serverThread = new Thread(new UppercaseWorker(requestSocket)); serverThread.start(); } }}

The server source code

Page 16: AspectJ - Java based AOP System

class UppercaseWorker implements Runnable { private Socket _requestSocket;

public UppercaseWorker(Socket requestSocket) throws IOException { System.out.println("Creating new worker"); _requestSocket = requestSocket; } public void run() { BufferedReader requestReader = null; Writer responseWriter = null; try { requestReader = new BufferedReader(new

InputStreamReader(_requestSocket.getInputStream())); responseWriter = new OutputStreamWriter(_requestSocket.getOutputStream());

Page 17: AspectJ - Java based AOP System

while(true) {String requestString = requestReader.readLine();if (requestString == null) {break;}System.out.println("Got request: " + requestString);responseWriter.write(requestString.toUpperCase() + "\n");responseWriter.flush();

} } catch(IOException ex) {}

finally { try { if (responseWriter != null) {responseWriter.close();} if (requestReader != null) {requestReader.close();} _requestSocket.close(); } catch (IOException ex2) {}}System.out.println("Ending the session");

}

}

Page 18: AspectJ - Java based AOP System

// ThreadPool.java - simple class that acts like stack for available threadsimport java.util.*;

public class ThreadPool {List _waitingThread = new Vector();

public void put(DelegatingThread thread) {System.out.println("Putting back: " + thread);_waitingThread.add(thread);

}public DelegatingThread get() { if (_waitingThread.size() != 0) { DelegatingThread availableThread =(DelegatingThread)_waitingThread.remove(0);

System.out.println("Providing for work: " + availableThread); return availableThread; }

return null;}

static class DelegatingThread extends Thread { private Runnable _delegatee; public void setDelegatee(Runnable delegatee) { _delegatee = delegatee; } public void run() {_delegatee.run();}

}}

Page 19: AspectJ - Java based AOP System

Adding thread pooling

// ThreadPooling.javapublic aspect ThreadPooling { ThreadPool pool = new ThreadPool();

//===================================================================== // Thread creation //===================================================================== pointcut threadCreation(Runnable runnable) : call(Thread.new(Runnable)) && args(runnable);

Thread around(Runnable runnable) : threadCreation(runnable) { ThreadPool.DelegatingThread availableThread = pool.get(); If (availableThread == null) {

availableThread = new ThreadPool.DelegatingThread(); } availableThread.setDelegatee(runnable); return availableThread; }

Page 20: AspectJ - Java based AOP System

Adding thread pooling (contd.)//=====================================================================// Session //=====================================================================pointcut session(ThreadPool.DelegatingThread thread): execution(void ThreadPool.DelegatingThread.run()) && this(thread);

void around(ThreadPool.DelegatingThread thread) : session(thread) { while(true) { proceed(thread); pool.put(thread); synchronized(thread) { try { thread.wait(); } catch(InterruptedException ex) {} } }}

Page 21: AspectJ - Java based AOP System

Adding thread pooling (contd.)//===========================================================

// Thread start //===========================================================pointcut threadStart(ThreadPool.DelegatingThread thread) : call(void Thread.start()) && target(thread);

void around(Thread thread) : threadStart(thread) { if (thread.isAlive()) { // wake it up synchronized(thread) { thread.notifyAll(); } } else { proceed(thread); }

}}

Page 22: AspectJ - Java based AOP System

The implementation in details• threadCreation() captures the creating a new thread object taking a Runnable

object as the argument. • Advise the threadCreation() pointcut to first check the thread pool for available threads. If no thread is available, create a new one. Set the delegatee to the Runnable object passed in and return that object. No proceed() so the actual operation is not executed

• session() captures the run() method's execution of any

ThreadPool.DelegatingThread objects.

Page 23: AspectJ - Java based AOP System

The implementation in details (contd.)• By putting session() inside a while(true) loop, you advise session() to never finish the servicing. That ensures a thread, once created, never dies. Once a request is processed, you put the thread back into thread pool and put the thread into waiting state.

• threadStart() captures a call to the Thread.start() method. It uses isAlive() to check if the thread previously started (thread obtained from a pool and now in a waiting state) Wake up the thread by notifying it. If the thread had not started yet, proceed

with starting the thread.

Page 24: AspectJ - Java based AOP System

Example 2 - Enforcement modularization

• Implement policy enforcement to ensure no duplicate listener are added to the models, and listeners do not loiter around when the view they represent become usable.

• Policy enforcement implementation in more useful and easy way - no documentation,code reviews and so on.

Page 25: AspectJ - Java based AOP System

Problems with listeners

• let you add a listener object more than once, which leads to duplicate work if an event-notification method carries an expensive operation.

• Easy to forget to remove listeners before destroying a view - cause the listener to consuming memory.

Page 26: AspectJ - Java based AOP System

aspect structural view

• need to implement 2 concerns:

– uniqueness concern

– no loitering-views concern

Page 27: AspectJ - Java based AOP System

Base aspect: EventListenerManagement

• This aspect contains an addListenerCall() pointcut that captures calls to methods adding a listener.

// EventListenerManagement.javaimport java.util.*;

public abstract aspect EventListenerManagement {pointcut addListenerCall(Object model, EventListener listener) : call(void *.add*Listener(EventListener+)) && target(model) && args(listener) && modelAndListenerTypeMatch();

abstract pointcut modelAndListenerTypeMatch();}

Page 28: AspectJ - Java based AOP System

Implement the uniqueness concern

• checks whether that listener was previously added. If that listener is already present, the operation does not proceed; otherwise, it adds the listener

• advises the addListenerCall() pointcut to check for the listener's uniqueness by looking in a list obtained by invoking getCurrentListeners(). It proceeds with adding the listener only if the list doesn't include a listener:

Page 29: AspectJ - Java based AOP System

Implement the uniqueness concern - contd.

• // EventListenerUniqueness.javaimport java.util.*;import javax.swing.*;import javax.swing.event.*;

import javax.swing.table.*;

public abstract aspect EventListenerUniqueness extends EventListenerManagement {void around(Object model, EventListener listener) : addListenerCall(model, listener) {

Page 30: AspectJ - Java based AOP System

Implement the uniqueness concern - contd.

• EventListener[] listeners = getCurrentListeners(model);if (!Utils.isInArray(listeners, listener)) {System.out.println("Accepting " + listener);proceed(model, listener);} else {System.out.println("Already listening " + listener);}}

public abstract EventListener[] getCurrentListeners(Object model);}

Page 31: AspectJ - Java based AOP System

Implement the uniqueness concern - contd.

• the concrete aspect TableModelListenerUniqueness extends EventListenerUniqueness to apply the aspect to TableModel and related classes. It provides an implementation for the modelAndListenerTypeMatch() pointcut to restrict the model type to AbstractTableModel and the listener type to TableModelListener.

Page 32: AspectJ - Java based AOP System

Implement the uniqueness concern - contd.

• // TableModelListenerUniqueness.javaimport java.util.EventListener;import javax.swing.event.TableModelListener;import javax.swing.table.*;

aspect TableModelListenerUniqueness extends EventListenerUniqueness {pointcut modelAndListenerTypeMatch() : target(AbstractTableModel) && args(TableModelListener);

public EventListener[] getCurrentListeners(Object model) {return ((AbstractTableModel)model).getListeners(TableModelListener.class); }}

Page 33: AspectJ - Java based AOP System

Implement a no loitering-views concern

• ensuring that no view loiters after its destruction.

• It advises addListenerCall() to proceed with the listener obtained by calling the getWeakListener() method.

Page 34: AspectJ - Java based AOP System

Implement a no loitering-views concern - contd.

• // EventListenerWeakening.javaimport java.lang.ref.*;import java.util.*;import javax.swing.event.*;

public abstract aspect EventListenerWeakening extends EventListenerManagement dominates EventListenerUniqueness {void around(Object model, EventListener listener) : addListenerCall(model, listener) {proceed(model, getWeakListener(listener));}public abstract EventListener getWeakListener(EventListener listener);}

Page 35: AspectJ - Java based AOP System

Implement a no loitering-views concern - contd.

• The TableModelListenerWeakening aspect handles table-related listeners. It uses a specialized WeakEventListener that implements TableModelListener by delegating to the referent object.

Page 36: AspectJ - Java based AOP System

Implement a no loitering-views concern - contd.

• // TableModelListenerWeakening.javaimport java.util.*;import javax.swing.event.*;import javax.swing.table.*;

public aspect TableModelListenerWeakening extends EventListenerWeakening {pointcut modelAndListenerTypeMatch() : target(AbstractTableModel) && args(TableModelListener);

public EventListener getWeakListener(EventListener listener) {System.out.println("Weakening " + listener);return new WeakTableModelListener((TableModelListener)listener);}}

Page 37: AspectJ - Java based AOP System

Implement a no loitering-views concern - contd.

•public class WeakTableModelListener extends WeakEventListener implements TableModelListener {

public WeakTableModelListener(TableModelListener delegatee) {super(delegatee);}

public void tableChanged(TableModelEvent e) {TableModelListener listener = (TableModelListener)getDelegatee();listener.tableChanged(e);}

Page 38: AspectJ - Java based AOP System

Implement a no loitering-views concern - contd.

•static aspect TableRemoveGarbageCollectedListeners extends WeakEventListener.RemoveGarbageCollectedListeners {

pointcut lexicalScopeMatch() : within(WeakTableModelListener);

public void removeListener(EventObject event, EventListener listener) {((TableModel)event.getSource()).removeTableModelListener((TableModelListener)listener);}}}

Page 39: AspectJ - Java based AOP System

Example 3: Characteristic-based implementation

modularization • Operations with the same characteristics

should typically implement common behaviors. for example you may need to authenticate access to all security-critical data.

Page 40: AspectJ - Java based AOP System

Characteristic-based implementation modularization• declare the aspect adding characteristic-

based crosscutting behavior as an abstract aspect.

• declare an abstract pointcut for methods with characteristics under consideration.

• write an advice performing the required implementation.

Page 41: AspectJ - Java based AOP System

SlowMethodAspect's implementation

• abstract slowMethods() pointcut and advises it to first put a wait cursor, proceed with the original operation, and finally restore the original cursor.

Page 42: AspectJ - Java based AOP System

SlowMethodAspect's implementation - contd.

• // SlowMethodAspect.javaimport java.util.*;import java.awt.*;import java.awt.event.*;

public abstract aspect SlowMethodAspect {abstract pointcut slowMethods(Component uiComp);

void around(Component uiComp) : slowMethods(uiComp) {Cursor originalCursor = uiComp.getCursor();Cursor waitCursor = Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);uiComp.setCursor(waitCursor);

Page 43: AspectJ - Java based AOP System

SlowMethodAspect's implementation - contd.

•try {proceed(uiComp);} finally {uiComp.setCursor(originalCursor);}}}

Page 44: AspectJ - Java based AOP System

SlowMethodAspect's implementation - contd.

• Two test components, GUIComp1 and GUIComp2, nest a concrete implementation of the aspect.

public static aspect SlowMethodsParticipant extends SlowMethodAspect {pointcut slowMethods(Component uiComp) : execution(void GUIComp1.performOperation1())&& this(uiComp);}

Page 45: AspectJ - Java based AOP System

SlowMethodAspect's implementation - contd.

public static aspect SlowMethodsParticipant extends SlowMethodAspect {pointcut slowMethods(Component uiComp) : (execution(void GUIComp2.performOperation1())|| execution(void GUIComp2.performOperation2()))&& this(uiComp);}