65
TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Techn ology 1 AspectJ™: aspect-oriented programming using Java™ technology Gregor Kiczales University of British Columbia and AspectJ.org

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology1 AspectJ™: aspect-oriented programming using Java™ technology Gregor Kiczales University

Embed Size (px)

Citation preview

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology1

AspectJ™:aspect-oriented programming usingJava™ technologyGregor KiczalesUniversity of British Columbia and AspectJ.org

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology2

my personal research goal

• to enable programmers to write codethat looks as much as possible like thedesign it implements

• code that “looks like the design”– same modularity and structure as design

• intended benefits– traceability is easier– easier to debug and maintain– more fun to write

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology3

my history with objects

• 81-84 – OO systems programming on the Lisp machine

• 85-92 – Common Lisp Object System

• 88-93 – metaobject protocols• 96-now – aspect-oriented

programming

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology4

Common Lisp Object System(CLOS)

• idea: integrate objects and Lisp• break OOP into constituent pieces

– polymorphic dispatch generic functions• multi-methods

– everything is an object• standard classes and built-in classes

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology5

generic function syntax

the syntax of a function call is the same asthe syntax of a generic function call

(car x)

(get-name p1)

(display item window)

(display item stream)

the caller can’t tell whether these are functions or generic functions

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology6

generic function syntax

the syntax of a function call is the same asthe syntax of a generic function call

(car x)

(get-name p1)

(display item window)

(display item stream)

• increases abstraction• means implementation can change• takes “message as goal” more seriously!• enables multi-methods

• (can’t add “real” multi-methods to Java)

each of these can have methods that dispatch based on the class of the arguments

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology7

CLOS was open source

• PCL implementation of CLOS– portable– high-performance– written in Common Lisp

• enabled users to be involved in design– all features had real user feedback before they

went into the standards document

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology8

CLOS Metaobject Protocol

• idea: everything is OO– including the programming language itself– metaobject protocol is meta-level framework– can change language semantics

• programmer could change– inheritance rules– kinds of methods– object implementation structure

• scope control– localized changes to specific parts of program

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology9

CLOS metaobject protocol

(draw obj)

generic function draw

class line

line obj

method for line

method for circle

doyou

apply? what is

your inheritance

?

apply yourself

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology10

aspect-oriented programming

• its hard to build with objects alone

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology11

a technical talk about how

a new programming paradigm, as realized in an

extension to the Java™ programming language

can improve programs,

and help with development

this talk…

a technical talk about how

a new programming paradigm, as realized in an

extension to the Java™ programming language

can improve programs,

and help with development

will show code & language details

aspect-oriented programming

AspectJ™

by improving their modularity

design, implementation & debugging

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology12

consider a system like

client1

client2

Serverclients call server

worker 1

worker 3

worker 2

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology13

OOP increases modularity

client1

client2

Serverclients call server

worker 1

worker 3

worker 2

– the data structure used to store– the search algorithm– the marshalling

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology14

but…

• context specific behavior here• synchronization• job logging•

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology15

but…

client1

client2

Serverclients call server

worker 1

worker 3

worker 2

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology16

but…Document

Printer

Userclass User { String name; int quota; User(String n) { name = n; }}

class Document { String name; Document(String n) { name = n; }}

Terminal

public class Printer { Thread pthread; boolean print(Document doc) { pthread = Thread.currentThread(); System.out.println("Printing " + doc.name); try { Thread.sleep(3000); } catch (InterruptedException e) { System.out.println("Print interrupted"); return false; }; return true; }

public void interruption(Document doc) { pthread.interrupt(); }}

public class Library { private Hashtable docs = new Hashtable(); private Hashtable users = new Hashtable();

private Printer printer; private class TerminalInfo { Terminal terminal; Thread thread; }; TerminalInfo term; Library(Printer p) { printer = p; for (int i = 0; i < 100 ; i++) { Document doc = new Document("book" + String.valueOf(i)); docs.put(doc, "book" + String.valueOf(i)); } for (int i = 0; i < 100 ; i++) { User user = new User("user" + String.valueOf(i)); users.put(user, "user" + String.valueOf(i)); } } public Document search(Terminal t, String key) { term.terminal = t; term.thread = Thread.currentThread(); try { return (Document)docs.get(key); } catch (Exception e) { System.out.println("Search interrupted at user's request"); } return null; } public boolean print(Terminal t, Document doc) { term.terminal = t; term.thread = Thread.currentThread(); try { return printer.print(doc); } catch (Exception e) { System.out.println("Print interrupted at user's request"); printer.interruption(doc); } return false; } public String quota(Terminal t, String username) { term.terminal = t; term.thread = Thread.currentThread(); try { User user = (User)users.get(username); if (user != null) return String.valueOf(user.quota); } catch (Exception e) { System.out.println("Quota query interrupted at user's request"); } return null; }

public void interruption(Terminal t) { if (t == term.terminal) { term.thread.interrupt(); } } public static void main(String[] args) { Printer printer = new Printer(); Library lib = new Library(printer); Terminal term = new Terminal(lib); }}

public class Terminal { private Library lib; Thread termthread;

Terminal (Library l) { lib = l; }

public void logon() {} public void gui() {}

public Document search(String key) { try { return lib.search(this, key); } catch (Exception e) { System.out.println("Operation interrupted at user's request"); lib.interruption(this); } return null; } public void print(Document doc) { try { lib.print(this, doc); } catch (Exception e) { System.out.println("Operation interrupted at user's request"); lib.interruption(this); } }

void interruption() { termthread.interrupt(); }

void run() { termthread = Thread.currentThread(); while (true) { } }}

Library • “tangled code”• code redundancy• difficult to reason

about• difficult to

change

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology17

but…client1

client2

Serverclients call server

worker 1

worker 3

worker 2

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology18

a crosscutting concernLibraryDocument

holds**

Terminal

accessed by

* Printer

uses

*

Userholds* search(key)

print(doc)quota(user)...

gui()logon()search(key)print(doc)...

print(ps)getStatus()getQueue()...

user interruptioncuts across theobject structure

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology19

the AOP idea

• crosscutting is inherent in complex systems• crosscutting concerns

– have a clear purpose– have a natural structure

• defined set of methods, module boundary crossings, points of resource utilization, lines of dataflow…

• so, let’s capture the structure of crosscutting concerns explicitly...– in a modular way– with linguistic and tool support

aspect-oriented programming

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology20

Document

Userclass User { String name; int quota; User(String n) { name = n; }}

class Document { String name; Document(String n) { name = n; }}

Terminal

public class Library { private Hashtable docs = new Hashtable(); private Hashtable users = new Hashtable();

private Printer printer; private class TerminalInfo { Terminal terminal; Thread thread; }; TerminalInfo term; Library(Printer p) { printer = p; for (int i = 0; i < 100 ; i++) { Document doc = new Document("book" + String.valueOf(i)); docs.put(doc, "book" + String.valueOf(i)); } for (int i = 0; i < 100 ; i++) { User user = new User("user" + String.valueOf(i)); users.put(user, "user" + String.valueOf(i)); } } public Document search(Terminal t, String key) { term.terminal = t; term.thread = Thread.currentThread(); try { return (Document)docs.get(key); } catch (Exception e) { System.out.println("Search interrupted at user's request"); } return null; } public boolean print(Terminal t, Document doc) { term.terminal = t; term.thread = Thread.currentThread(); try { return printer.print(doc); } catch (Exception e) { System.out.println("Print interrupted at user's request"); printer.interruption(doc); } return false; } public String quota(Terminal t, String username) { term.terminal = t; term.thread = Thread.currentThread(); try { User user = (User)users.get(username); if (user != null) return String.valueOf(user.quota); } catch (Exception e) { System.out.println("Quota query interrupted at user's request"); } return null; }

public void interruption(Terminal t) { if (t == term.terminal) { term.thread.interrupt(); } } public static void main(String[] args) { Printer printer = new Printer(); Library lib = new Library(printer); Terminal term = new Terminal(lib); }}

public class Terminal { private Library lib; Thread termthread;

Terminal (Library l) { lib = l; }

public void logon() {} public void gui() {}

public Document search(String key) { try { return lib.search(this, key); } catch (Exception e) { System.out.println("Operation interrupted at user's request"); lib.interruption(this); } return null; } public void print(Document doc) { try { lib.print(this, doc); } catch (Exception e) { System.out.println("Operation interrupted at user's request"); lib.interruption(this); } }

void interruption() { termthread.interrupt(); }

void run() { termthread = Thread.currentThread(); while (true) { } }}

Library

Printerpublic class Printer { Thread pthread; boolean print(Document doc) { pthread = Thread.currentThread(); System.out.println("Printing " + doc.name); try { Thread.sleep(3000); } catch (InterruptedException e) { System.out.println("Print interrupted"); return false; }; return true; }

public void interruption(Document doc) { pthread.interrupt(); }}

language support for aspects

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology21

OOP – the motivation

void drawWindow(Window w) { drawBorders(w.borders); if ( w.isPopUp ) { …}

got to get this code

OO was about localizingthis kind of concern

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology22

OOP – the language technology

• explicit support for– message as goal– encapsulation– polymorphism– inheritance

• some variation– class- vs. prototype-based

• Java, C++, Smalltalk, CLOS vs. Self– single vs. multiple inheritance

• Java, Smalltalk, Self vs. C++, CLOS

interface FigureElement { public void draw(Graphics g);}

class Point implements FigureElement { int _x = 0, _y = 0; : public void draw(Graphics g) { <do own thing> }}

class Line implements FigureElement { : public void draw(Graphics g) { <do own thing> }}

analogy as follows?

interface – crosscut

class – aspect

advice – method

analogy as follows?

interface – crosscut

class – aspect

advice – method

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology23

OOP – the tool technology

• tools preserve object abstraction– browse classes and methods– debug objects and methods

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology24

an example systema distributed digital library

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology25

the codeDocument

Printer

Userclass User { String name; int quota; User(String n) { name = n; }}

class Document { String name; Document(String n) { name = n; }}

Terminal

public class Printer { Thread pthread; boolean print(Document doc) { pthread = Thread.currentThread(); System.out.println("Printing " + doc.name); try { Thread.sleep(3000); } catch (InterruptedException e) { System.out.println("Print interrupted"); return false; }; return true; }

public void interruption(Document doc) { pthread.interrupt(); }}

public class Library { private Hashtable docs = new Hashtable(); private Hashtable users = new Hashtable();

private Printer printer; private class TerminalInfo { Terminal terminal; Thread thread; }; TerminalInfo term; Library(Printer p) { printer = p; for (int i = 0; i < 100 ; i++) { Document doc = new Document("book" + String.valueOf(i)); docs.put(doc, "book" + String.valueOf(i)); } for (int i = 0; i < 100 ; i++) { User user = new User("user" + String.valueOf(i)); users.put(user, "user" + String.valueOf(i)); } } public Document search(Terminal t, String key) { term.terminal = t; term.thread = Thread.currentThread(); try { return (Document)docs.get(key); } catch (Exception e) { System.out.println("Search interrupted at user's request"); } return null; } public boolean print(Terminal t, Document doc) { term.terminal = t; term.thread = Thread.currentThread(); try { return printer.print(doc); } catch (Exception e) { System.out.println("Print interrupted at user's request"); printer.interruption(doc); } return false; } public String quota(Terminal t, String username) { term.terminal = t; term.thread = Thread.currentThread(); try { User user = (User)users.get(username); if (user != null) return String.valueOf(user.quota); } catch (Exception e) { System.out.println("Quota query interrupted at user's request"); } return null; }

public void interruption(Terminal t) { if (t == term.terminal) { term.thread.interrupt(); } } public static void main(String[] args) { Printer printer = new Printer(); Library lib = new Library(printer); Terminal term = new Terminal(lib); }}

public class Terminal { private Library lib; Thread termthread;

Terminal (Library l) { lib = l; }

public void logon() {} public void gui() {}

public Document search(String key) { try { return lib.search(this, key); } catch (Exception e) { System.out.println("Operation interrupted at user's request"); lib.interruption(this); } return null; } public void print(Document doc) { try { lib.print(this, doc); } catch (Exception e) { System.out.println("Operation interrupted at user's request"); lib.interruption(this); } }

void interruption() { termthread.interrupt(); }

void run() { termthread = Thread.currentThread(); while (true) { } }}

Library

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology26

language support for aspectsDocument

Userclass User { String name; into quota; User(String n) { name = n; }}

class Document { String name; Document(String n) { name = n; }}

class UserRequestThreads { introduction (Terminal | Library | Printer) { Thread thread;

void interruption() { thread.interrupt(); } }

static advice (Document search(String key) | void print(Document doc)) & Terminal { catch (Exception e) { System.out.println("Operation interrupted at user's request"); lib.interruption(thisJoinPoint.object); } } static advice (Terminal & (Document search(String key) | void print(Document doc))) | (Library & (Document search(Terminal t, String key) | String quota(Terminal t, String username) | boolean print(Terminal t, Document doc))) | (Printer & boolean print(Document doc)) { before { thread = Thread.currentThread(); } } static advice Library & (Document search(Terminal t, String key) | String quota(Terminal t, String username)) { catch (Exception e) { System.out.println("Search interrupted at user's request"); return null; } } static advice Library & boolean print(Terminal t, Document doc) { catch (Exception e) { System.out.println("Search interrupted at user's request"); printer.interruption(doc); return false; } } static advice Printer & boolean print(Document doc) { catch (InterruptedException e) { System.out.println("Print interrupted"); return false; } }}

UserInterrupt

Terminalpublic class Terminal { private Library lib; Terminal (Library l) { lib = l; }

public void logon() {} public void gui() {}

public Document search(String key) { return lib.search(this, key); } } public void print(Document doc) { lib.print(this, doc); }

void run() { termthread = Thread.currentThread(); while (true) { } }}

Librarypublic class Library { private Hashtable docs = new Hashtable(); private Hashtable users = new Hashtable();

private Printer printer; private class TerminalInfo { Terminal terminal; }; TerminalInfo term;

Library(Printer p) { printer = p; for (int i = 0; i < 100 ; i++) { Document doc = new Document("book" + String.valueOf(i)); docs.put(doc, "book" + String.valueOf(i)); } for (int i = 0; i < 100 ; i++) { User user = new User("user" + String.valueOf(i)); users.put(user, "user" + String.valueOf(i)); } }

public Document search(Terminal t, String key) { term.terminal = t; return (Document)docs.get(key); }

public boolean print(Terminal t, Document doc) { term.terminal = t; return printer.print(doc); }

public String quota(Terminal t, String username) { term.terminal = t; User user = (User)users.get(username); if (user != null) return String.valueOf(user.quota); }

public static void main(String[] args) { Printer printer = new Printer(); Library lib = new Library(printer); Terminal term = new Terminal(lib); }}

Printerpublic class Printer { boolean print(Document doc) { System.out.println("Printing " + doc.name); try { Thread.sleep(3000); } catch (InterruptedException e) { System.out.println("Print interrupted"); return false; }; return true; }}

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology27

AspectJ

• support for explicitly crosscutting concerns• smooth integration with Java• adds 3 new constructs

LibraryDocument

TerminalPrinter

User

make modules like this first class

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology28

return _x; return _y;

semantic framework for Java

when a “void setX(int)”message* is received bya point, do this

p1

setX(3)

_x = x;

class Point { private int _x = 0, _y = 0;

Point(int x, int y) { setXY(x,y); }

int getX() { return _x; } int getY() { return _y; }

void setX(int x) { _x = x; } void setY(int y) { _y = y; }

void setXY(int x, int y) { _x = x; _y = y; }

void draw(Graphics g) { … }}

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology29

a Client

a Server

the join pointskey points in runtime object

interactiona return valueor exception

is received bythis object an value is

returned or an exception is thrown by this object

a method is called on an

object

dispatch

dispatch

the method callleaves this object

the actual method starts

executinga method call

to another object

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology30

pointcut requests(): Server & (int newJob(String) | String jobStatus(int));

the pointcut construct

any point in aninstanceof Server

whenever a Server receives“int newJob(String)” or “String jobStatus(int)” calls

<a point>

setY(11)

setX(3)

a “void setX(int)” message

and or

a “void setY(int)” messagename and parameters

denotes certain join points

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology31

the crosscut constructcan cut across multiple classes

crosscut moves(): (Point & (void setX(int) | void setY(int))) | (Line & (void setP1(Point) | void setP2(Point)));

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology32

the advice constructadditional action to take at crosscut

crosscut moves(): (Point & (void setX(int) | void setY(int))) | (Line & (void setP1(Point) | void setP2(Point)));

static after(): moves() { <runs after moves> }

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology33

class TrackMoves {

static boolean _flag = false; static boolean testAndClear() { boolean result = _flag; _flag = false; return result; }

crosscut moves(): (Point & (void setX(int) | void setY(int))) | (Line & (void setP1(Point) | void setP2(Point)));

static after(): moves() { _flag = true; }}

a simple aspectan aspect is a crosscutting

concern

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology34

using context in advice• crosscut can explicitly expose certain

values• advice can use value

crosscut moves(Object o): o & ((Point & (void setX(int) | void setY(int))) | (Line & (void setP1(Point) | void setP2(Point))));

static after(Object o): moves(o) { <o is bound to object> }

crosscut signature

typed variable in place of type name

matches signatureadvice parameters

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology35

using context in advice

class TrackMoves {

static Set _movers = new HashSet(); static Set getMovers() { Set result = _movers; _movers = new HashSet(); return result; }

crosscut moves(Object o): o & ((Point & (void setX(int) | void setY(int))) | (Line & (void setP1(Point) | void setP2(Point))));

static advice(Object o): moves(o) { after { _movers.add(o); } }}

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology36

advice is

additional action to take at a join points

• before before proceeding at join point

• after returning a value to join point• after throwing a throwable to join point• after return to join point either way

• around before, with explicit control overwhen&if program proceeds atjoin point

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology37

after adviceclass BoundsChecker {

crosscut sets(Point p): p & (void setX(int) | void setY(int));

static advice (Point p): sets(p) { after { assert(p.getX() >= MIN_X); assert(p.getX() <= MAX_X); assert(p.getY() >= MIN_Y); assert(p.getY() <= MAX_Y); } }

static void assert(boolean v) { if ( !v ) throw new RuntimeException(…); }}

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology38

before adviceclass BoundsChecker {

static advice(Point p, int newX): p & void setX(newX) { before { assert(newX >= MIN_X); assert(newX <= MAX_X); } } static advice(Point p, int newY): p & void setY(newY) { before { assert(newY >= MIN_Y); assert(newY <= MAX_Y); } } static void assert(boolean v) { if ( !v ) throw new RuntimeException(…); }}

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology39

around adviceclass BoundsEnforcer {

static advice(Point p, int newX) returns void: p & void setX(newX) { around { thisJoinPoint.runNext(p, clip(newX, MIN_X, MAX_X)); } }

static advice(Point p, int newY) returns void: p & void setY(newY) { around { thisJoinPoint.runNext(p, clip(newY, MIN_X, MAX_X)); } }

static int clip(int val, int min, int max) { return Math.max(min, Math.min(max, val)); }}

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology40

an asymmetric multi-object protocol

time each connection

total timeconnected Customer

Connection

0..N

11

caller

receiver

1Call

0..N

trivial telecom system

crosscutting concerns are: timingconsistency checks...

start timing: when there’s a new connectionstop timing: when connection is dropped

add time: when connection is dropped

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology41

timing aspect implementationclass Timing {

private Timer Connection.timer = new Timer();

private long Customer.totalConnectTime = 0;

public static long getCustomerTotalConnectTime(Customer c) { return c.totalConnectTime; }

: :

a variable in Connection that only Timing can see

a variable in Customer that only Timing can see

proper accessor for the total connect time

the aspect state crosscuts the objectsproper access is through the aspect

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology42

timing aspect implementation

crosscut startTiming(Connection c): c & void complete(); crosscut endTiming(Connection c): c & void drop();

static advice(Connection c): startTiming(c) { after { c.timer.start(); } }

static advice(Connection c): endTiming(c) { after { c.timer.stop(); c.getCaller().totalConnectTime += c.timer.getTime(); c.getReceiver().totalConnectTime += c.timer.getTime(); } }}

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology43

wildcarding in crosscuts

Point & public * *(..)shapes..* & !private int *(..) messages

instantiations(Point | Line) & new(..)shapes..* & new(..)

shapes.util.Pointshapes..* types

“..” is a multiple-part wild card“*” is a single-part wild card

* *(..) & handle(RMIException) handling exceptions

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology44

property-based crosscuts

• consider another programmer adding public method– i.e. extending the public interface

• this code will automatically capture that

class LogPublicErrors {

static Log log = new Log();

crosscut publicInterface (): mypackage..* & ( public * *(..) | public new(..) );

static advice(): publicInterface() { after throwing (Error e) { log.write(e); } }}

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology45

context-dependent functionality

client1

client2

Serverclients call server

worker 1

worker 3

worker 2

server ends up calling workers, through

many levelsworkers need to know client:• capabilities• charge backs• to customize result

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology46

context passing crosscuts

client1

client2

Server

worker 1

worker 3

worker 2

crosscut entryPoints(): Server & (void doService1(Object) | void doService2());

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology47

context passing crosscuts crosscut entryPoints(): Server & (void doService1(Object) | void doService2());

crosscut invocations(Client c): c & calls(entryPoints());

client1

client2

Server

worker 1

worker 3

worker 2

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology48

context passing crosscuts crosscut entryPoints(): Server & (void doService1(Object) | void doService2());

crosscut invocations(Client c): c & calls(entryPoints());

crosscut clientScope(Client c): cflow(invocations(c));

client1

client2

Server

worker 1

worker 3

worker 2

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology49

context passing crosscuts crosscut entryPoints(): Server & (void doService1(Object) | void doService2());

crosscut invocations(Client c): c & calls(entryPoints());

crosscut clientScope (Client c): cflow(invocations(c)) & workPoints();

crosscut workPoints(): (ServiceHelper1 & void doWorkItemA()) | (ServiceHelper2 & void doWorkItemB()) | (ServiceHelper3 & void doWorkItemC());

client1

client2

Server

worker 1

worker 3

worker 2

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology50

class HandleChargebacks { crosscut entryPoints(): Server & (void doService1(Object) | void doService2());

crosscut invocations(Client c): c & calls(entryPoints());

crosscut clientWork(Client c): cflow(invocations(c)) & workPoints();

crosscut workPoints(): (ServiceHelper1 & void doWorkItemA()) | (ServiceHelper2 & void doWorkItemB()) | (ServiceHelper3 & void doWorkItemC());

static advice (Client c): clientWork(c) { before { c.chargeback(); } }}

context passing crosscuts

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology51

IDE demos

• basic support, in emacs and Visual Studio– browsing program structure– editing– compiling

• extension to javadoc• will expand in future releases

– debugger– more sophisticated browsing– more IDEs

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology52

AspectJ – libraries

• 2 things this could mean– libraries of crosscutting concerns– libraries of objects with crosscutting concerns

• language must support– inheritance & specialization of aspects– composition of aspects (advice & crosscuts)

• key points– libraries evolve, come later, are really valuable

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology53

inheritance and specialization

• crosscuts can have additional advice– in figure editor– moves() can have advice from different parts

of system

• abstract crosscuts can be specialized

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology54

a reusable exception handling aspect

abstract public class LogRemoteExceptions {  abstract crosscut msgs();  static advice msgs() { after throwing (RemoteException e) { log.println(“Remote call failed in: ” + thisJoinPoint.methodName + “(” + e + “).”); } }}

public class JWAMRemotExceptionLogger extends LogRemoteExceptions {  crosscut msgs(): RegistryServer & * *(..) | RMIMessageBrokerImpl & private * *(..);}

abstract

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology55

common questions• how do I start?

– very conservative• use AO style

– somewhat conservative -• debugging, tracing, profiling

– somewhat aggressive• use where crosscutting concerns are hurting most

– more aggressive• re-factor all existing code

• back-out is straightforward in all cases

• but how do I find the crosscutting concerns?

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology56

other common aspects

• concurrency control (locking)• contracts (pre-/post- conditions)• initialization & cleanup

– especially of linked structures

• security• GUI “skins”• some patterns• common protocols

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology57

common questions

• is this just event based programming? reflection?

• doesn’t _____ have a feature like this?Visual Age, CLOS, Objective-C

– crosscutting concerns are an old problem– crystallization of style around explicit support

for implementation of crosscutting concerns

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology58

common questions

• doesn’t this violate modularity?– new kind of modularity– aspects are constrained

• composition of aspects?

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology59

common questions• does this really help?• these examples are all simple

• OOP doesn’t shine when implementing just MenuOOP shines when doing window system, w/GUI frameworks – consider larger systems– consider multiple crosscutting aspects– consider reading someone else’s code

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology60

common questions• exception handling case study*• framework w/ 600 classes, 44 KLOC• reengineered with AspectJ 0.4

2.9%10.9%

.2 KLOC (31 catch aspects)

2.1 KLOC (414 catch statements)

.6 KLOC pre-conditions

.3 KLOC post-conditions2.1 KLOC pre-conditions .6 KLOC post-conditions

with aspectswithout aspects

% of total LOC

exceptionhandling

exceptiondetection

* to appear in ICSE’2000

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology61

related work

in separation of crosscutting concerns• HyperJ [Ossher, Tarr et. al]

– multi-dimensional separation of concerns– generator-based approach

• Composition Filters, Demeter/Java• OpenC++, OpenJIT, …• Intentional Programming• active community…

– publishes and holds workshops at: OOPSLA, ECOOP and ICSE

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology62

AspectJ status

• aspectj.org– 250 unique users download each month– users list grew from 35 to 379 members since August

• compiler implementation– 4 major and 16 minor releases over the last year

• still needs to support incremental compilation• still depends on javac as a back-end

• tutorials, primer, users-guide– full-day tutorials grew from 3 in 1998 to 8 in 1999

• tools support– initial IDE support for emacs, VisualStudio, need more– javadoc replacement – ajdoc, need jdb

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology63

AspectJ futurecontinue to build language, compiler, tools and user

community; community feedback will drive design

• 1.0– crosscutting state, type system, tuning existing constructs– no longer dependent on javac– ajdb; JBuilder and Forte support

• 1.1– only minor language changes– faster incremental compiler (up to 5k classes), doesn’t require

source of target classes– ???

• 2.0– new dynamic crosscut constructs, ...

commercialization decision sometime after 1.0

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology64

AOP future

• language design– more dynamic crosscuts, type system …

• tools– more IDE support, aspect discovery, re-factoring, re-

cutting…

• software engineering– finding aspects, modularity principles, …

• metrics– measurable benefits, areas for improvement

• theory– type system for crosscutting, fast compilation, advanced

crosscut constructs

TS-1505, AspectJ: Aspect-Oriented Programming Using JavaTM Technology65

putting things that usually get spread out in one place…

putting things that usually get spread out in one place… by improving

their modularity

by improving their modularity

this is a technical talk about how

a new programming paradigm, as realized in an

extension to the Java™ programming language

can improve programs,

and help with development

aspect-oriented programmingaspect-oriented programming

aspectjaspectj

design, implementation, debugging…design, implementation, debugging…

will show code, language detailswill show code, language details