Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lecture 21: Crosscutting Aspect-Oriented Programming

Similar presentations


Presentation on theme: "Lecture 21: Crosscutting Aspect-Oriented Programming"— Presentation transcript:

1 David Evans http://www.cs.virginia.edu/~evans
Lecture 21: Crosscutting Aspect-Oriented Programming "...feels like I've died and gone to Java Heaven." Don Asumu, Planning Tools Technical Development Leader, BT Laboratories on StructureBuilder, commercial tool based on Aspect-Oriented Programming, at Background just got here last week finished degree at MIT week before Philosophy of advising students don’t come to grad school to implement someone else’s idea can get paid more to do that in industry learn to be a researcher important part of that is deciding what problems and ideas are worth spending time on grad students should have their own project looking for students who can come up with their own ideas for research will take good students interested in things I’m interested in – systems, programming languages & compilers, security rest of talk – give you a flavor of the kinds of things I am interested in meant to give you ideas (hopefully even inspiration!) but not meant to suggest what you should work on CS655: Programming Languages University of Virginia Computer Science David Evans

2 University of Virginia CS 655
Menu Self-Application Answer Sorting in Linda Aspect-Oriented Programming “Separation of Concerns” Examples D (Distributed Language) AspectJ Adaptive Programming 14 November 2018 University of Virginia CS 655

3 Programming Paradigms
All the languages we have seen so far are “Generalized Procedure” languages: Programs organized into procedures Procedures may be grouped and associated with data Some programs have properties (“aspects”) that cross-cut procedures Examples: communication, synchronization, handling interrupts, security, loop fusion, etc. 14 November 2018 University of Virginia CS 655

4 Aspect-Oriented Programming
Components (Functional Units) Aspect Weaver Procedural Program Aspects (Non-functional Units) Compiler Executable 14 November 2018 University of Virginia CS 655

5 AO programming vs. idioms
Slide adapted from Gregor Kiczales ICSE Workshop Talk AO programming vs. idioms class Book { private String title; private PostScript ps; private String isbn; private String author; private User borrower; author = a; title = t; public Book(String t, String a, String i, PostScript p) { isbn = i; } ps = p; public void set_borrower(User u) {borrower = u;} public User get_borrower() {return borrower;} public PostScript get_ps() { return ps; } public class PrinterImpl { Vector jobs; String status = “Idle” pubilc get_status() { return status } public PrinterImpl() {} } jobs.add(j); public add_job(int j) { class Book { private UserID borrower; private PostScript ps; private BookID id; id = new BookID(t,a,i); public Book(String t, String a, String i, PostScript p) { } ps = p; public PostScript get_ps() { return ps; } public void set_borrower(UserID u) {borrower = u;} public UserID get_borrower() {return borrower;} public BookID get_bid() { return id; } private String title; class BookID { public BookID(String t, String a, String i) { private String isbn; private String author; isbn = i; author = a; title = t; public String get_title() {return title;} class User { Printer thePrinter; Library theLibrary; private UserID id; public boolean getBook (String title) { public User(String n) { id = new UserID(n); } BookID aBook=null; try{ try { } catch (RemoteException e) {} aBook = theLibrary.getBook(id, title); thePrinter.print(id, aBook); } public UserID get_uid() { return id; } return true; private String name; class UserID { public String get_name() { return name; } public UserID(String n) { name = n; } Classes Aspect Weaver Library theLibrary; private String name; class User { Printer the; Printer public User(String n) { name = n; } public boolean getBook (String title) { return true; thePrinter.print(this,aBook); Book aBook = theLibrary.getBook(this, title); } class Library { Hashtable books; } books = new Hashtable(100); Library(){ public Book getBook(User u, String title) { Book b = (Book)books.get(title); if(books.containsKey(title)) { System.out.println("REQUEST TO GET BOOK " + title); System.out.println("getBook: Found it:" + b); b.set_borrower(u); if (b.get_borrower() == null) if (b != null) { return b; return null; interface PrinterInterface extends Remote { } throws RemoteException; public boolean print (UserID u, BookID b) implements PrinterInterface { public class Printer extends UnicastRemoteObject private Vector jobs = new Vector(10, 10); private Library theLibrary; public Printer() throws RemoteException{} PostScript ps=null; throws RemoteException{ try{ ps = theLibrary.getBookPS(b); return queue(newJob); Job newJob = new Job (ps, u); } catch (RemoteException e) {} //... boolean queue(Job j) { return true; interface LibraryInterface extends Remote { } public PostScript getBookPS(BookID bid) throws RemoteException; public BookID getBook(UserID u, String title) throws RemoteException; Library() throws RemoteException { Hashtable books; class Library extends UnicastRemoteObject implements LibraryInterface { books = new Hashtable(100); throws RemoteException { public BookID getBook(UserID u, String title) Book b = (Book)books.get(title); if(books.containsKey(title)) { System.out.println("REQUEST TO GET BOOK " + title); if (b.get_borrower() == null) System.out.println("getBook: Found it:" + b); if (b != null) { return b.get_bid(); b.set_borrower(u); return null; public PostScript getBookPS(BookID bid) Book b = (Book)books.get(bid.get_title()); if (books.containsKey(bid.get_title())) { return b.get_ps(); if (b != null) book: Book: {direct pages;} void print(Book book) { portal Printer { } portal Library { Book: {copy title, author, isbn;} return: Book find (String title){ } Aspects class Book { private UserID borrower; private PostScript ps; private BookID id; String i, PostScript p) { public Book(String t, String a, } ps = p; id = new BookID(t,a,i); public PostScript get_ps() { return ps; } public void set_borrower(UserID u) {borrower = u;} public UserID get_borrower() {return borrower;} public BookID get_bid() { return id; } private String title; class BookID { private String isbn; private String author; author = a; title = t; public BookID(String t, String a, String i) { isbn = i; public String get_title() {return title;} Library theLibrary; private UserID id; class User { Printer thePrinter; public User(String n) { id = new UserID(n); } try{ BookID aBook=null; public boolean getBook (String title) { try { } catch (RemoteException e) {} aBook = theLibrary.getBook(id, title); thePrinter.print(id, aBook); return true; public UserID get_uid() { return id; } } private String name; class UserID { public String get_name() { return name; } public UserID(String n) { name = n; } interface PrinterInterface extends Remote { } throws RemoteException; public boolean print (UserID u, BookID b) implements PrinterInterface { public class Printer extends UnicastRemoteObject private Vector jobs = new Vector(10, 10); private Library theLibrary; public Printer() throws RemoteException{} PostScript ps=null; throws RemoteException{ try{ ps = theLibrary.getBookPS(b); return queue(newJob); Job newJob = new Job (ps, u); } catch (RemoteException e) {} //... boolean queue(Job j) { return true; interface LibraryInterface extends Remote { public BookID getBook(UserID u, String title) throws RemoteException; } public PostScript getBookPS(BookID bid) throws RemoteException; Library() throws RemoteException { Hashtable books; class Library extends UnicastRemoteObject implements LibraryInterface { books = new Hashtable(100); throws RemoteException { public BookID getBook(UserID u, String title) Book b = (Book)books.get(title); if(books.containsKey(title)) { System.out.println("REQUEST TO GET BOOK " + title); if (b != null) { System.out.println("getBook: Found it:" + b); if (b.get_borrower() == null) return b.get_bid(); b.set_borrower(u); return null; public PostScript getBookPS(BookID bid) Book b = (Book)books.get(bid.get_title()); if (books.containsKey(bid.get_title())) { return b.get_ps(); if (b != null) 14 November 2018 University of Virginia CS 655

6 University of Virginia CS 655
Join Points Aspects defined at “Join Points” Typically, method invocations, entry and exits Not limited to that – defined by aspect language Aspect languages are domain specific Define code or transformations to occur at join points 14 November 2018 University of Virginia CS 655

7 University of Virginia CS 655
What is an aspect? Definition 1: A modular unit that has no stand-alone function That is, it requires a context in order to function And, that effects other modular units Definition 2: Something that implements properties that are not well-captured by functional units 14 November 2018 University of Virginia CS 655

8 University of Virginia CS 655
D Jcore – component language (Java subset, removed synchronization) Cool – aspect language for expressing coordination of threads Ridl – aspect language for expressing remote access strategies Join Points – method invocations Weaver just needs to put code at method entrances and exits Can produce Java source code to compile normally 14 November 2018 University of Virginia CS 655

9 University of Virginia CS 655
Cool Define coordinators that specify locking semantics: selfexclusive (method executed by at most one thread at a time) mutexclusive (methods in same set cannot be executed concurrently) Guarded suspension – define monitor-like abstractions separate from implementations Can access, but not modify instance variables 14 November 2018 University of Virginia CS 655

10 Cool Example coordinator BoundedStackCoord : BoundedStack {
selfexclusive { pop, push }; mutexclusive { pop, push }; cond boolean full = false; cond boolean empty = true; push : requires !full; on_exit { empty = false; if (sp == MAX) full = true; } pop : requires !empty; on_exit { full = false; if (sp == 0) empty = true; } } Ties aspect to specific implementation! 14 November 2018 University of Virginia CS 655

11 Ridl Control remote method invocations
Gives programmer control over copying semantics in parameter passing (can elect to copy just parts of object graph) remote Printer { Static print (Document: copy *.int, *.String, documentRepository)); ... } Only copy int and String fields, and reference to documentRepository. 14 November 2018 University of Virginia CS 655

12 University of Virginia CS 655
AspectJ crosscuts identify events Can be associated with method calls, exception handlers advice defines code associated with crosscuts 14 November 2018 University of Virginia CS 655

13 Tangled Example: Java API
package java.io; public class File implements java.io.Serializable { private String path; ... public boolean exists() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkRead(path); } return exists0(); public boolean canRead() { return canRead0(); Exact same code, repeated 8 times in java.io.File Why not make it a procedure? Performance (method call overhead) Better error messages (?) 14 November 2018 University of Virginia CS 655

14 University of Virginia CS 655
Cross-cuts crosscut name(context): event list crosscut fileReaders(java.io.File f): java.io.File & (boolean exists() | boolean canRead() | boolean canRead() | boolean isDirectory() | long lastModified() | long length() | String[] list() | String[] list(FilenameFilter filter)) Wildcards crosscut nonStatics (): java.io.* & !static * (..); crosscut intMethods (): MyClass & public * (int); crosscut returnObject (): * & Object * (..); crosscut ioHandlers (): Account & * (..) & catch (IOException); 14 November 2018 University of Virginia CS 655

15 University of Virginia CS 655
Advice advice (Parameters) : crosscut advice checkRead (java.io.File f): fileReaders (f) { before { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkRead (path); } 14 November 2018 University of Virginia CS 655

16 AspectJ File Implementation
Aspects shown on previous slides Simple implementation with security code removed package java.io; public class File implements java.io.Serializable { private String path; ... public boolean exists() { return exists0(); } public boolean canRead() { return canRead0(); } 14 November 2018 University of Virginia CS 655

17 Is AspectJ version better?
Advantages Compact program Separate concerns without any performance cost Easier to change and reuse Easier to understand and analyze policy Disadvantages Have to learn a new language Extra compilation step Debugging may be difficult (but special-purpose tools) 14 November 2018 University of Virginia CS 655

18 Example: Exception Handling
[Lippert & Lopes, 99] Exception handling code clutters (and often dwarves) normal code Tangled exceptions limit reuse Cannot change exceptional behavior without overriding entire method Tangled exceptions lose abstraction All methods must handle network failures by retrying is scattered throughout code (and easy to forget) 14 November 2018 University of Virginia CS 655

19 University of Virginia CS 655
JWAM Experiment Java framework Designed around design-by-contract with explicit calls to Contract.require and Contract.ensure Use AspectJ to abstract out crosscut for contracts and exception handling 11% of original code dealt with exception detection and handling; many handlers do the same thing 14 November 2018 University of Virginia CS 655

20 University of Virginia CS 655
Bank Account public class Account { public Account (String owner, int accNo) { Contract.require (owner != null && owner.length() > 0); Contract.require (accNo > 0); this.owner = owner; this.accNo = accNo; } public void deposit (float amount) { Contract.require (amount > 0.0); balance += amount; ... 14 November 2018 University of Virginia CS 655

21 Aspect-Oriented Implementation
class AccountContract { static advice Account & new(String s, int n) { before { Contract.require (s != null && s.length () > 0); Contract.require (n > 0); } } static advice Account & deposit (float f) { before { Contract.require (f > 0.0); } } 14 November 2018 University of Virginia CS 655

22 Handling Library Exceptions
Typical code: try { registry.put (name, this); } catch (RemoteException e) { ErrorLog.print (“Remote call failed: ” + e); } Replace with: crosscut remoteHandlers () : * & * *(..) & catch (RemoteException); static advice remoteHandlers () { ErrorLog.print (“Remote call failed in ” thisMethodName + “:” + e); } 14 November 2018 University of Virginia CS 655

23 University of Virginia CS 655
Results Reduced exception detection and handling code by a factor of 4.5 Removed many simple conditions (null tests of results and arguments in contracts), common exception handlers Is resulting code likely to be more reliable and maintainable? 14 November 2018 University of Virginia CS 655

24 Adaptive Programming: Demeter
Instance of AOP [Lieberherr92] Aspects are traversal strategies Separate the program text and the class structure Program is independent of class graph Accomplish tasks by traversals Specification for what parts of received object should be traversed Code fragments for what to execute when specific object types are encountered 14 November 2018 University of Virginia CS 655

25 University of Virginia CS 655
Law of Demeter Law of Demeter: a method should talk only to its friends: arguments and part objects (computed or stored) newly created objects Dilemma: Small method problem of OO (if followed) Unmaintainable code (if not followed) Traversal strategies are the solution to this dilemma Demeter = Greek Goddess of Agriculture (grow software from small blocks) 14 November 2018 University of Virginia CS 655

26 AP Example: UML Class Diagram
Slide adapted from Karl Lieberherr talk AP Example: UML Class Diagram busStops BusRoute BusStopList buses 0..* BusStop BusList waiting 0..* passengers Example for developing strategies and writing adaptive programs Bus PersonList Person 0..* 11/14/2018 AOP/Demeter

27 Collaborating Classes
Slide adapted from Karl Lieberherr talk Collaborating Classes Find all persons waiting at any bus stop on a bus route busStops BusRoute BusStopList OO solution: one method for each red class buses 0..* BusStop BusList waiting 0..* passengers Bus PersonList Person 0..* 11/14/2018 AOP/Demeter

28 Java Solution (excerpt)
class BusRoute { BusStopList busstops; void printWaitingPassengers () { busstops->printWaitingPassengers (); } } class BusStopList { BusStop stops[]; for (int i = 0; i < stops.length; i++) stops[i].printWaitingPassengers (); 14 November 2018 University of Virginia CS 655

29 University of Virginia CS 655
Java Solution (cont.) class BusStop { PersonList waiting; void printWaitingPassengers () { waiting.print (); } } class PersonList { Person people[]; void print () { for (int i = 0; i < people.length; i++) people[i].print (); } class Person { String name; void print () { System.stdout.println (name); } } 14 November 2018 University of Virginia CS 655

30 University of Virginia CS 655
Demeter Approach Devise a traversal strategy Specify code for different types of objects reached on a traversal Example: code prints name if object is a Person Independent of class graph 14 November 2018 University of Virginia CS 655

31 Slide adapted from Karl Lieberherr talk
Traversal Strategy First try: from BusRoute to Person busStops BusRoute BusRoute BusStopList BusStopList buses 0..* BusStop BusStop BusList BusList waiting 0..* passengers Bus Bus PersonList PersonList Person Person 0..* 11/14/2018 AOP/Demeter

32 Slide adapted from Karl Lieberherr talk
Traversal Strategy from BusRoute through BusStop to Person busStops BusRoute BusStopList buses 0..* BusStop BusList waiting 0..* passengers Bus PersonList Person 0..* 11/14/2018 AOP/Demeter

33 Writing Adaptive Programs with Strategies
Slide adapted from Karl Lieberherr talk Writing Adaptive Programs with Strategies strategy: from BusRoute through BusStop to Person BusRoute { traversal waitingPersons(PersonVisitor) { through BusStop to Person; } // from is implicit void printWaitingPersons() // traversal/visitor weaving instr. = waitingPersons(PrintPersonVisitor); PrintPersonVisitor { before Person () < do printing >} can we really program with strategies? Here is how. 11/14/2018 AOP/Demeter

34 Robustness of Strategy
Slide adapted from Karl Lieberherr talk Robustness of Strategy from BusRoute bypassing Bus to Person villages BusRoute BusStopList buses VillageList busStops 0..* 0..* BusStop BusList Village waiting 0..* passengers Bus PersonList Person 0..* 11/14/2018 AOP/Demeter

35 Filter out noise in class diagram
Slide adapted from Karl Lieberherr talk Filter out noise in class diagram only three out of seven classes are mentioned in traversal strategy! from BusRoute through BusStop to Person explain why strategy better replaces traversal methods for the classes BusRoute VillageList Village BusStopList BusStop PersonList Person 11/14/2018 AOP/Demeter

36 University of Virginia CS 655
Summary Aspect-Oriented Programming and Adaptive Programming provide programmers with new expressive options Active research area (Separation of Concerns Workshops at OOPSLA, ICSE, ECOOP, etc.) Many directions to explore Practical use still remains to be seen Kiczales paper claims like OO in 1980 (by induction) But some commercial success Tendril Software (Adaptive programming tools for Java), bought by BEA Systems. 14 November 2018 University of Virginia CS 655

37 University of Virginia CS 655
Charge Next time: John Thornley Project Progress If your implementation will not be complete by Monday morning, schedule a meeting with me now 14 November 2018 University of Virginia CS 655


Download ppt "Lecture 21: Crosscutting Aspect-Oriented Programming"

Similar presentations


Ads by Google