Open Collections

UBC Theses and Dissertations

UBC Theses Logo

UBC Theses and Dissertations

Tool support for understanding and diagnosing pointcut expressions Ye, Lingdong 2007

Your browser doesn't seem to have a PDF viewer, please download the PDF to view this item.

Item Metadata

Download

Media
831-ubc_2007-0646.pdf [ 2.84MB ]
Metadata
JSON: 831-1.0052055.json
JSON-LD: 831-1.0052055-ld.json
RDF/XML (Pretty): 831-1.0052055-rdf.xml
RDF/JSON: 831-1.0052055-rdf.json
Turtle: 831-1.0052055-turtle.txt
N-Triples: 831-1.0052055-rdf-ntriples.txt
Original Record: 831-1.0052055-source.json
Full Text
831-1.0052055-fulltext.txt
Citation
831-1.0052055.ris

Full Text

Tool Support For Understanding and Diagnosing Pointcut Expressions by Lingdong Ye  B.Eng., Southwest University of Finance and Economics, 1998 B . S c , McMaster University, 2005  A T H E S I S S U B M I T T E D IN P A R T I A L F U L F I L M E N T O F T H E REQUIREMENTS F O R T H E D E G R E E OF Master of Science in The Faculty of Graduate Studies (Computer Science)  The University Of British Columbia August 31, 2007 © Lingdong Ye 2007  Abstract Writing correct AspectJ pointcuts is hard. This is partly because of the complexity of the pointcut language and partly because it requires understanding how a pointcut matches across the entire code base. In this thesis, we present algorithms that compute two kinds of useful information that can help AspectJ developers diagnose and fix potential problems with their pointcuts. First, we present an algorithm to compute almost matched join points. Second we present algorithms to compute explanations of why a pointcut does not match (or does match) a specific join point. We implemented two tools using these algorithms. The first is an offline tool that analyzes a code base and produces a comprehensive report. Using this tool, we were able to find several real problems in existing, medium-sized AspectJ code bases. The second tool is an Eclipse plugin called PointcutDoctor. PointcutDoctor is a natural extension of A J D T , the mainstream I D E for AspectJ. It provides developers easy access to the same information from within their already familiar development environment.  Table of Contents Abstract  ii  T a b l e of C o n t e n t s  iii  L i s t of Tables  v  List of Figures  vi  Acknowledgments 1  vii  Introduction  1  1.1 1.2 1.3 1.4  1 1 4 7  1.5 1.6 1.7  Thesis Statement AspectJ and Aspect Oriented Programming Existing I D E Support for Writing AspectJ Pointcuts Motivating Examples 1.4.1 Example 1 1.4.2 Example 2 Algorithms to Compute Useful Information Contributions Overview of the Thesis  . . . .  7  8 9 10 10  2  P o i n t c u t D o c t o r : A n Extension of A J D T 2.1 PointcutDoctor 2.1.1 Almost matched join point shadows 2.1.2 Pointcut explainer 2.2 A Use Case 2.3 Summary  12 12 12 14 14 15  3  Computing Almost Matched Join Points 3.1 Pointcut Relaxation 3.1.1 Step 1: Preprocessing 3.1.2 Step 2: Relaxing Conjunctions  16 16 17 17  iii  Table of Contents 3.2 3.3 3.4 4  5  Virtual Shadows Related Work Summary  '. ,  •  Pointcut Explanation 4.1 Computing Color-coded Highlighting Explanation 4.1.1 Converting Pointcuts into Propositional Formulas 4.1.2 Key Definitions 4.2 The Algorithm 4.3 Algorithm Variants 4.4 Computing Textual Explanation 4.5 Summary Evaluation 5.1 Case Study Procedures 5.2 Results •. . • 5.3 Performance Impact 5.4 Summary  '  19 21 21  . . .  22 22 22 23 24 28 29 31 35 35 37 40 40  6  Limitations and Future W o r k 6.1 Limitation of Implementation 6.2 Limitation of Evaluation 6.3 Summary  41 41 41 42  7  Conclusion  43  Bibliography  44  iv  List of Tables 3.1  Relaxers  20  4.3 4.1 4.2 4.4  Explanation Messages Not-match Explanation Heuristics Match Explanation Heuristics Conventions used in Table 4.1 and Table 4.2  30 32 33 34  5.1  Messages Issued and Number of Bugs Found in Case Study (Lldentified, C:Connrmed, R:Real bugs, V : "Virtual" bugs) . .  38  v  List of Figures 1.1  A J D T ' s Cross References View showing a list of matches . . .  5  1.2  One of A J D T ' s warning messages if no match  6  2.1  Screenshot of PointcutDoctor  13  5.1  A Sample of the Report Used in Case Study  36  Acknowledgments I thank my supervisors Kris De Voider and Gregor Kiczales for their guidance, support and encouragement that make this work possible. Thanks to them for being supportive for me to work on the thesis in another city. Thanks to them for all the insightful discussions that will continue to guide my whole career life. I thank Gail Murphy for being my second reader and giving me invaluable comments. Thanks to all the great friends I've met in Vancouver for making it such an amazing experience. 1  vii  Chapter 1  Introduction 1.1  Thesis Statement  In this thesis, we present algorithms to compute two kinds of information about AspectJ [14] pointcuts: almost matched join points and explanation on why a pointcut does not match (or does match) a given join point. We claim that this information can help a developer find problems in existing pointcuts. We also claim that this information can be added to an existing integrated development environment (IDE) in a logical and clean way. In the following sections, we first introduce the background information about AspectJ, Aspect-Oriented Programming, pointcuts and current I D E support for writing pointcuts. We then illustrate that pointcuts are hard to write, and that current AspectJ I D E tools do not provide sufficient support for writing AspectJ pointcuts. Finally, we explain how we will prove our thesis and outline the key contributions of this thesis.  1.2  AspectJ and Aspect Oriented Programming  AspectJ is an extension to the Java programming language that provides support for Aspect-Oriented Programming (AOP) in a Java-like syntax. Aspect-Oriented Programming [15] is a new programming paradigm that attempts to improve modularity of software systems. It provides support for modularizing crosscutting concerns using a new language construct, aspect. Crosscutting concerns refer to concerns that cut across other concerns, and thus, conflict with them in terms of system decomposition. Crosscutting concerns cannot be well modularized using mainstream programming methodologies, such as procedural programming and object-oriented programming. Using mainstream programming methodologies, if we try to modularize crosscutting concerns, other concerns will be scattered across many modules. We next illustrate the concepts of crosscutting concern and pointcut using the code of a simple figure editor. In the following code, class Shape is  1  Chapter 1. Introduction  the common super class for all shapes in the system. There are two kinds of shapes in the system, Point and Line. Class Display manages the shapes drawn on the screen. abstract c l a s s Shape { Color c o l o r ; public void setColor(Color t h i s . c o l o r = c;  c) {  } }  c l a s s Point extends Shape { i n t x, y; p u b l i c v o i d s e t X ( i n t x) { t h i s . x = x; } p u b l i c v o i d s e t Y ( i n t y) { t h i s . y = y; } }  c l a s s Line extends Shape { Point p i , p2; p u b l i c v o i d s e t P l ( P o i n t p) { t h i s . p l = p; } p u b l i c v o i d s e t P 2 ( P o i n t p) { t h i s . p 2 = p; }  } c l a s s Display { public s t a t i c void r e f r e s h O { } }  2  Chapter 1.  Introduction  Let's consider the implementation of a display-refresh concern: to refresh the display whenever any type of shape changes. Its implementation in Java requires adding a line D i s p l a y . r e f r e s h O in every method that renders a change of any type of shape. These methods include Shape. s e t C o l o r ( C o l o r ) , P o i n t . s e t X ( i n t ) , P o i n t . s e t Y ( i n t ) , L i n e . s e t P l ( P o i n t ) and L i n e . s e t P 2 ( P o i n t ) . We say this display-refresh concern is a crosscutting concern because it cuts across the existing system decomposition. As a result, its implementation in Java scatters across multiple modules, i.e. classes and methods. In AspectJ, we can modularize this concern using the following aspect without the need to modify any class above: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.  aspect D i s p l a y R e f r e s h i n g { / / The P o i n t c u t p o i n t c u t shapeChange(): e x e c u t i o n ( v o i d S h a p e . s e t C o l o r ( C o l o r ) ) II execution(void Point.setX(int)) | | execution(void P o i n t . s e t Y ( i n t ) ) | | execution(void Line.setPl(Point)) I I execution(void Line.setP2(Point)); / / The Advice after():shapeChange() { Display. refreshO ;  11. } 12. }  In the above code, line 3-7 declares a pointcut that captures execution of all methods that will change the state of a shape. Pointcut is an AspectJ language construct that is used to pick out dynamic join points, well-defined events in the execution of a program, such as method execution, object instantiation and field access. Every dynamic join point has a corresponding static shadow in the source code or byte code of the program, which is called join point shadow[13). For simplicity, in this thesis, when we say that a pointcut matches a join point shadow, we mean that the pointcut matches the join points that correspond to the join point shadow. Primitive pointcuts such as c a l l , e x e c u t i o n and set specify the kind and other characteristics of the expected join points. Primitive pointcuts can be combined using logical operators including && ( A N D ) , I I (OR) and ! (NOT). The example pointcut above has the semantics "to pick up join points at the execution of method Shape . s e t C o l o r ( C o l o r ) , or execution of method P o i n t . s e t X ( i n t ) or 3  Chapter 1. Introduction Line 9-11 is an advice that defines the behavior after the state of a shape is changed: to refresh the display. Advice'is an AspectJ language construct that defines the behavior of the aspect at the the join points specified by the pointcut.  1.3  Existing IDE Support for Writing AspectJ Pointcuts  It is important to note that tool support is essential for effectively working with AspectJ code and pointcuts in particular. First, aspects potentially affect the entire code base. The AspectJ pointcut language is powerful and is designed to be capable of picking up join points arising from the entire code base. For instance, in the previous example we can write a pointcut e x e c u t i o n ( * * . s e t * ( . .)) and an advice that refreshes the display when every method whose name starts with string "set" gets executed, no matter in which class those methods are declared. Second, there is nothing in the source code of those affected methods that describes or refers to the pointcut or advice. This absence of information has been called obliviousness [11] [12] [16] [8] by the A O P community. The obliviousness characteristic of A O P is necessary for modularizing crosscutting concerns, because it allows crosscutting concerns to be expressed in separate modules without modifying the code that they crosscut with. But controversially, it also makes the code harder to read and maintain. Tools that explicitly reveal and display the correlation between aspects and the code affected by them help to improve the readability and maintainability of A O P code. AspectJ Development Tools ( A J D T ) [1], a plug-in of the Eclipse platform [3], is a mainstream I D E for AspectJ. A J D T provides support for writing pointcuts by showing a list of advisees for the selected advice (i.e. matches for the pointcut) in a Cross References View. A screenshot of A J D T with its Cross References View open is shown in Figure 1.1. A J D T also issues some compiler warning messages for several cases of suspicious code, for example, when the pointcut of an advice does not match any join points (as shown in Figure 1.2). In the next section, we are going to see why such information is insufficient for a developer to ascertain the correctness of her pointcuts, as well as to diagnose the problems in her pointcuts.  4  W= Java - spacewar/src/spacewar/SoundEffi File  Edit  Source  Refactor  e ! # '  J r J '  Navigate  Search  Q-~  ~.'%  %  Project  ~ -\ IB  in!*]  Help  Run  11 Sfc Java  \B  i CVS Reposi.. :__ Missile java 1  j  Ci Debug.aj  'i SoundEffect.a]  J J  SoundEffectaj  SimpIeErrors.aj  d  //' a d d s o u n d e f f e c t , fox : //  - fire,  //  will  //  and t h e volume be a c c o r d i n g  —I  I t h e sound e f f e c t  to t h e i n i t i a l p o s i t i o n  of the b u l l e t .  //  use: playSound(String  pointcut  type,  f i r e ( d o a b l e x, d o a b l e  d o u b l e x,  double y i  y > : c a l l (Bullet-f.new(..) )  Sfiwithincode (void S h i p . f i r e ( ) )  ££args(*,x,y,..t ; after(doable if  x,  ( b u l l e t  doable y ) r e t u r n i n g ( B u l l e t b u l l e t i : f i r e ( x , y ) instanceof  {  Missile)  p l a y S o u n d ( " i r a s s i l e F i r e d " , x, y) ; else  p l a y S o u n d ( " f c u l l e t F i r e d " , x, y ) ;  J" Problem j  k  Javadoc  Declarat  •  Console C  Progres | _, History  Synchro I []•: Outline f Wi Cross R  afterReturning(double, double)  Pj -<i>  advises ship: constructor-call(void spacewar.Bullet.<init>(spacevvar.Game, double, double, double, double)}  :  {-}  •  (-> BigShip: constructor-call(void spacewar.Missile.<init>(spacewar.Game, double, double, double, double))  Writable  Smart Insert  i 24 : 43  Figure 1.1: A J D T ' s Cross References View showing a list of matches  3  p o i n t c u t g e t S x z e ( ) : c a l l < * B u l l e t . g e t S x z e (..)}; before f):getSize{)  {  }  IL.  jj  '  lUttlll  ! 1 Problems 23 \ J a v a d o c j Declaration; C o n s o l e Progress History: Synchronize! Outflne] Cross References; 0 errors, 2 warnings, 0 infos [j Description * I t 3 !*: W a r n i n g s ( 2 i t e m s ) 1!  A does net match because declaring type is spacewar.SpaceObject, if match desired use tarqet(spacewar.Guilet) [XlintiunmatchedSuperTypelnCail]  A does not match because declaring type is spacewar.SpaceObject, if match desired use target(spacev.<ar.Butlet} tXlint:unmatchedSuperTypeBiCatl]  Figure 1.2: One of A J D T ' s warning messages if no match  Chapter 1. Introduction  1.4  Motivating Examples  To write a correct pointcut, a developer needs to understand how the pointcut matches across her entire code base, as well as the subtleties of the pointcut language. In this section we provide two examples to illustrate these two requirements respectively. 1.4.1  Example 1  Ascertaining that a pointcut is correct in a given code base requires a global understanding of the code at a level of detail that is not easy to obtain or remember for developers. To assist developers, A J D T provides an explicit representation of the join points a pointcut matches in a given code base, i.e., a list of matches in its Cross References View. We believe that.this information is insufficient for a developer to determine a pointcut's correctness. We illustrate this problem with a concrete example which was taken from [17]: pointcut connectionCreation(String u r l , S t r i n g username,String password) : c a l l ( p u b l i c s t a t i c Connection DriverManager.getConnection(String, String, String)) && a r g s ( u r l , username, password);  This pointcut matches the calls to method getConnection of DriverManager that have three S t r i n g parameters. The args pointcut binds the three parameters of the method call to variables so that they can be used later. Assume that a developer formulated this pointcut to capture the creation of database connections by calling related methods in DriverManager class. How would the developer know that this pointcut is correct? Since the intention is to capture all creations, verifying correctness means ascertaining that there are no accidentally missed creation sites. A J D T ' s cross references view shows which join point shadows produce join points that are matched by the pointcut, but it does not show any explicit information about join points that are not being matched. Consequently the view does not help to discover unintended misses. Indeed, it is hard for a developer to scan a list of matches and realize something that should be there is not. However this kind of determination is often critical in understanding whether a pointcut is correct. For example, there are three getConnection methods declared in DriverManager that can be used to create database'connections: 7  Chapter 1. Introduction DriverManager.getConnection(String,String,String) DriverManager.getConnection(String, P r o p e r t i e s ) DriverManager.getConnection(String) Only calls to the first of these 3 methods are matched by the example pointcut. The pointcut is therefore incorrect, since it fails to match calls to the other two. Because A J D T ' s cross references view provides no explicit information about non-matched join points, it provides little help to discover this important fact. As a result the bug in the pointcut is likely to go unnoticed. A tool that shows explicitly information about unmatched join points could help developers avoid this kind of unintended misses. 1.4.2  Example 2  Another difficulty with regard to pointcut writing is the complexity of the pointcut language semantics itself. Consider for example the following pointcut: pointcut f i r e ( ) : call(Bullet.new(..)) && w i t h i n c o d e ( v o i d S h i p . f i r e ( ) ) W i l l the following constructor calls be matched by this pointcut? c l a s s BigShip extends Ship { public void f i r e ( ) { B u l l e t b l = new B u l l e t ( n u l l , 0, 0 ) ; B u l l e t b3 = new M i s s i l e ( n u l l , 0, 0 ) ;  //(D //(2)  }  }  Intuitively, this pointcut matches calls to the constructor of B u l l e t in the lexical scope of S h i p . f i r e ( ) . However, the reality of how the pointcut actually matches in this eample might be surprising to some developers: the join point corresponding to (1) is matched, while the join point corresponding to (2) is not. First of all, both calls pass the test withincode ( v o i d S h i p . f i r e ( ) ) , though neither of them are in S h i p . f i r e . This is because withincode not only matches join point shadows within the specified method, but also implicitly matches join points shadows within all the methods that override it, so ( 1 ) is matched. Second, although M i s s i l e is a subclass of B u l l e t ) , (2) is not matched. This is because the c a l l pointcut does not match any calls to constructors for subtypes of the type specified in 8  Chapter 1. Introduction the pointcut. These and other complexities of the AspectJ pointcut language and the Java language make writing correct pointcuts difficult. A J D T only provides limited support for explaining a pointcut, e.g. the warning message shown in Figure 1.2. We believe that a tool that offers an explanation of why a certain join point is matched or not matched could help developers diagnose problems with their pointcuts.  1.5  Algorithms to Compute Useful Information  The examples in the previous section motivate that it would be useful to show information about non-matched join points to developers as well as explanations about why a pointcut matches or does not match certain join points. This thesis contributes algorithms to compute such information. Our first algorithm computes almost matched join points. We use a technique we call pointcut relaxation that uses simple heuristics to provide a more nuanced notion of "almost matched" than existing algorithms. Our algorithm also computes virtual join point shadows to handle possible evolutions of the code base. We also contribute several algorithms that compute two kinds of explanations to help a developer understand and diagnose problems in her pointcuts. The first computes a color-coded highlighting of a pointcut expression that shows which parts of the pointcut expression are responsible for the non-match(or match). The second produces a text message explaining why a highlighted part matches (or does not match) the given join point. We claim that the information discussed above can help a developer find problems in her pointcuts. We also claim that this information can be added to existing I D E in a logical and clean way. To prove our first claim, we developed an offline tool that produces a comprehensive report about all the pointcuts in a given code base. We applied this tool to the code bases of two medium-sized AspectJ projects in different domains (AspectJ refactored jEdit [9] and ORBacus [18]). We found that even in a relatively stable code base developed by experienced programmers there are still problems in the pointcuts due to programmers' incomplete knowledge of the code base or confusion about the AspectJ pointcut language. This shows that the information computed by our algorithms can help a developer find problems in her pointcuts. To prove our second claim, we developed an Eclipse plugin called Point-  9  Chapter 1. Introduction cutDoctor . PointcutDoctor extends A J D T seamlessly to provide developers easy access to the same information from within their familiar development environment. This shows that this information can be added to existing . I D E in a logical and clean way. 1  1.6  Contributions  This thesis makes the following contributions: • We present our pointcut relaxation algorithm to compute almost matched join point shadows. Our algorithm is more sophisticated and provides a more nuanced notion of "almost matched" than the boundary join points technique previously proposed by Anbalagan and Xie [5]. We will discuss these differences in detail in Chapter 3. • We present algorithms that explain why a pointcut does not match (or does match) join points produced by a given join point shadow and provide improvement suggestions. • We developed a user interface that is a natural extension to A J D T on Eclipse and shows this information to developers from within their familiar development environment. • We show that the information on almost matched join points and the explanations computed by our algorithms can be used to find problems with pointcuts in real AspectJ code.  1.7  Overview of the Thesis  The remainder of this thesis is organized as follows: Chapter 2 presents PointcutDoctor, our I D E tool implemented as an extension of A J D T . This shows how the information our algorithms compute can be made accessible from within the I D E , and thus supports our second claim. We choose to discuss about PointcutDoctor first because it will give readers a more intuitive overview of the idea behind this thesis by seeing how the information our algorithms compute is used in a concrete IDE. Chapter 3 discusses our algorithm and heuristics to compute almost matched join point shadows. Chapter 4 gives the pointcut explanation algorithm as well as the heuristics for providing the detailed textual explanation. Chapter 5 presents our case 1  PointcutDoctor: http://pointcutdoctor.cs.ubc.ca  10  Chapter 1. Introduction studies on two m e d i u m sized code base. C h a p t e r 6 presents some of the l i m i t a t i o n s of our algorithms,. of their current i m p l e m e n t a t i o n a n d o f the evaluation presented i n this thesis, a n d some ideas o n how these could lead to future work. C h a p t e r 7 presents our conclusions.  11  Chapter 2  PointcutDoctor: An Extension of A J D T In this chapter, we demonstrate PointcutDoctor, an extension to A J D T that provides developers two kinds of information about AspectJ pointcuts: almost matched join points and an explanation on why a pointcut does not match (or does match) a given join point. We can see how PointcutDoctor adds the information to existing I D E in a logical and clean way. This proves our second claim of our thesis. We choose to discuss the I D E tool first because it provides an intuitive overview of the idea behind this thesis .by seeing how the information our algorithms compute is used in a concrete IDE.  2.1  PointcutDoctor  The user interface of PointcutDoctor is designed to be non-disruptive to the users who are already familiar with A J D T . A l l features are integrated into the current A J D T user interface without introducing any new views. The existing A J D T interface is preserved and extended with some additional behavior in a clean and logical way. The main point where PointcutDoctor functionality has been added is in the cross references view. The two major features are discussed below. 2.1.1  A l m o s t matched join point shadows  First, as discussed in Chapter 1, the original A J D T cross references view only displays information about matched join point shadows (see Figure 1.1). As shown in Figure 2.1, PointcutDoctor extends this with an additional list of almost matches. Notice also that some of the almost matched shadows are marked as "virtual". Our algorithm produces virtual shadows for.calls to methods that have been declared but for which no actual calls exist within the code base. The rationale behind this is that even though such calls do not exist in the current code base it is possible, and perhaps likely, that they 12  p o i n t c u t b u i i e t C r e a t i o n (Game game,- B u l l e t .bullet).:... . c a l l (Bui l e t .new (Game, d o u b l e , d o u b l e , d o u b l e , d o u b l e ) ) ccargs(game) Sttarcjet ^ u l l e t )  M J  1  ^  • Constructor calis don't have "target"..Use the advice after(...) returning] , (...) to capture the object being created: '_• . •'-  a f t e r (Game, game, B i i i x C i , . ^ i ^ i . w - - " « ^ ^ ^ " ^ ^ " t H " ^ i f - J ' « J - ' t ' - w - i - . i i f (bullet instaneeof H i s s i l e ) playSound("missileFired") ; else playSound("taulletFired");  Problems,} Javadocj ^ d ^ £ j ^ ] | £ [ 9 0  r e s s  Q K biJetCreatk)n(6arne, Bufet) B - «*> almost matched join points f I <-> KgShp: constructor-cal(void Missile.<init>(6ame,double,double double,double)) | |.{-> • on ^tJi I- t< i r-4(y/< ,it n M ( G i r i f d>i bl^: d'Lj!~,d i '[•' /inLib'^Vj /  r  )  «- H (wtual) constructor-ca8(vojd Bullet.<init>(double,double,Game)) 4> matched join points  Figure 2.1:  Screenshot of PointcutDoctor  • ...-  Chapter 2. PointcutDoctor: An Extension of AJDT will be added in future versions and a developer should take such potential join points into account when trying to write "robust" pointcuts. 2.1.2  Pointcut explainer  The second extension is a pointcut explanation feature that is closely integrated into A J D T ' s cross references view and editor. As shown in Figure 2.1, when the developer clicks on a shadow in the cross references view PointcutDoctor provides an explanation by highlighting specific parts of the pointcut right in the editor. The highlighted parts are those that are responsible for matching or not matching this join point shadow. The highlighting uses a color-coding scheme based on the matching status of the pointcut fragment. Three highlighting colors are chosen for "Matching" (colored green), "Not matching" (colored red) and "Maybe" (colored yellow), where "Maybe" indicates that matching requires runtime determination. If the colored highlighting alone is not a sufficient explanation, the developer may elicit more information by hovering over the highlighted part of the pointcut to request an explanation why this particular pointcut fragment is colored the way it is. The textual explanation elaborates the causes and tries to educate the user on the subtleties of AspectJ and provides suggestions for improving the pointcut. The explanations are tailored to the specific context of the user's code.  2.2  A Use Case  Figure 2.1 shows the screenshot of PointcutDoctor in a typical scenario. A user writes a pointcut and finds an expected join point shadow appear in the list of almost matches. She clicks on that join point shadow in the cross references view of A J D T . The responsible fragments are highlighted in two different colors: args(game) and t a r g e t ( b u l l e t ) are in red indicating that they do not match the selected join point shadow, and withincode are in green indicating that it matches. Because she is not sure why t a r g e t ( b u l l e t ) does not match the join point shadow, she moves her mouse over that fragment. A tooltip shows up explaining why this fragment does not match and providing suggestion to include this join point shadow.  14  Chapter 2. PointcutDoctor: An Extension of AJDT  2.3  Summary  In this chapter, we showed PointcutDoctor, an extension to A J D T that provides developers two kinds of information about AspectJ pointcuts: almost matched join points and an explanation on why a pointcut does not match (or does match) a given join point. PointcutDoctor provides developers easy access to the information from within their already familiar development environment. This chapter proves the second claim of our thesis, the information computed by our algorithm can be added to existing I D E in a clean and logical way.  15  Chapter 3  Computing Almost Matched Join Points In this chapter we present our algorithm to compute almost matched join point shadows. We use a technique we call pointcut relaxation. We also propose virtual join point shadows to handle the possible evolution of the code base. Finally, we will discuss how our algorithms are different from some existing work.  3.1  Pointcut Relaxation  Pointcut relaxation is the process of slightly modifying the original pointcut to produce relaxed pointcuts so that they match more join points than the original one. We can compute almost matched join point shadows from the difference of the sets of matches for the relaxed pointcuts and the original pointcut. As previously noted, pointcut relaxation is similar to Anbalagan and Xie's method of computing boundary join points [5]. However, pointcut relaxation provides a'more nuanced notion of "almost matched" and provides support for virtual join point shadows in potential future versions of the code. A more detailed comparison of the two techniques can be found in Section 3.3. A pointcut is relaxed in two steps—preprocessing and conjunction relaxation. The overall process is as shown below: Set<Pointcut> r e l a x ( P o i n t c u t p o i n t c u t ) { /* Step 1: p r e p r o c e s s i n g */ P o i n t c u t ptcDNF = convertToDNF( dropNegation(pointcut)); /* Step 2: r e l a x i n g conjunctions */ Set<Pointcut> r e l a x e d P o i n t c u t s =• (/>; f o r each c o n j u n c t i o n p i n ptcDNF 16  Chapter 3. Computing Almost Matched Join Points  { Set<Pointcut> p t c s = r e l a x C o n j u n c t i o n ( p ) ; relaxedPointcuts = relaxedPointcuts | J ptcs;  } return relaxedPointcuts;  } 3.1.1  Step 1: Preprocessing  In the preprocessing step, all negation pointcuts (pointcuts proceeded by a !) are dropped and the resulting pointcut is then converted into Disjunctive Normal Form ( D N F ) . Dropping negations relaxes a pointcut allowing it to match join points excluded by the negated expression. Dropping negations also has the advantage that it greatly reduces the complexity of the resulting D N F . Dropping negated parts of a pointcut is straightforward and conversion to D N F is a standard technique [7], so we.will not elaborate on the preprocessing step any further. Pointcut relaxation is simplified by this preprocessing step because we can just relax the conjunctions in the D N F separately in the following steps. 2  3.1.2  Step 2: Relaxing Conjunctions  In the second step, each conjunction (primitive pointcuts connected by &&) of the resulting D N F will be relaxed separately, and the results are recombined. This step is driven by a set of heuristic rules. We used instructional books ([17], [10]), web resources ([4]), and the result of a study on the AspectJuser mailing list [2], as guidelines to devise these heuristics. In our mailing list study, we identified and classified 67 discussion topics about pointcut writing in the topics posted from M a y 2005 to December 2006. Relaxers are defined for different parts of a pointcut. Specifically, for primitive pointcuts that have method/field signatures ( c a l l , execution, get, set, withincode, p r e / i n i t i a l i z a t i o n ) , a relaxer is assigned to each component of their signature patterns, such as the return type pattern, the declaring type pattern and the parameter list pattern. For other primitive pointcuts, a relaxer is assigned to the whole pointcut. Some relaxers are capable of applying different relaxation methods based on heuristics that analyze both the pointcut and the code base to which it is being matched. D N F is a standard notion in logic as described in [7], e.g., (a A b A c) V (d A e) is in D N F , while (a V b) A c is not. 2  17  Chapter 3. Computing Almost Matched Join Points Table 3.1 elaborates the different relaxers used in PointcutDoctor and our reporting tool. The pseudo code for relaxing conjunctions is given below: Set<Pointcut> r e l a x C o n j u n c t i o n ( P o i n t c u t ptcConjunction)  { List<Relaxer> candidates = c r e a t e R e l a x e r s ( ptcConjunction); sortRelaxersByPrecedence(candidates); List<Relaxer> s e l e c t e d R e l a x e r s = s e l e c t F i r s t N ( candidates, N); Set<Pointcut> r e l a x e d P o i n t c u t s = </>; a p p l y A H R e l a x e r s ( p t c C o n j u n c t i o n , 0, selectedRelaxers, relaxedPointcuts); return relaxedPointcuts;  } void applyAHRelaxers(Pointcut pointcut, i n t index, List<Relaxer> s e l e c t e d R e l a x e r s , Set<Pointcut> r e l a x e d P o i n t c u t s )  { if  (index<selectedRelaxers.sizeO) { Set<Pointcut> relaxedByOne = selectedRelaxers[index].relax(pointcut); f o r each r e l a x e d P o i n t c u t i n relaxedByOne a p p l y A H R e l a x e r s ( r e l a x e d P o i n t c u t , index+1, selectedRelaxers, relaxedPointcuts); } else relaxedPointcuts.add(pointcut);  } First, a list of candidate relaxers are generated for the non-wildcard parts in the original pointcut. For example, for pointcut c a l l ( * Foo . b a r ( i n t ) ) && t a r g e t ( f ) , the candidate list consists of DeclaringTypeRelaxer, NameRelaxer, ParamsRelaxer and ThisOrTargetRelaxer. Next, the list of candidate relaxers is sorted using a heuristic rule based on our intuition determining their precedence. The precedence of relaxers used in PointcutDoctor and our reporting tool is defined as follows: 3  3  A non-wildcard part refers to a pointcut part that is neither a * nor . .  18  Chapter 3. Computing Almost Matched Join Points ParamsRelaxer > ArgsRelaxer > AnnotationRelaxer > M o d i f i e r R e l a x e r > ThrowRelaxer > ReturnTypeRelaxer > HandlerRelaxer > DeclaringTypeRelaxer > ThisOrTargetRelaxer > W i t h i n R e l a x e r > NameRelaxer The first N most significant relaxers will be selected for the next step, where N is a configurable parameter that can be changed to produce more or less almost matched join point shadows. In our current implementation, an experimental value of 6 is initially assigned, to N . In addition, we restrict N to be less than the number of non-wildcard parts in the pointcut to avoid creating an overly-broad relaxed pointcut (one that matches every join point). The effect of this constraint on N is to relax specific pointcuts more than generic ones. This approach seems to work well in practice. Finally, the selected relaxers are executed to relax all applicable parts in the pointcut depending on the conditions defined in each relaxer. Note that it is possible that the conditions of multiple relaxation methods in a relaxer (e.g. DeclaringTypeRelaxer) are satisfied simultaneously. In such cases, multiple relaxed pointcuts will be created. We use the relaxed pointcuts and a modified AspectJ weaver to compute almost matched join point shadows. To compute almost matched join point shadows, we augmented the original AspectJ weaver to match the relaxed pointcuts in parallel with the original pointcut.  3.2  Virtual Shadows  In some cases, even when a join point does not exist in the current code base, it is very likely these join points will occur in future versions of the code, e.g. if a method is declared but not used (this is often the case when using code libraries). Our tool is able to detect this case and identify these virtual join point shadows as matched/almost matched join point shadows. This technique is implemented by augmenting the weaving process of AspectJ compilation. The AspectJ compiler produces instances of different subclasses of its abstract Shadow class when visiting each join point shadow in the code base and matches these shadows against each applicable pointcut. We introduce a group of virtual shadow classes that extend the Shadow class and that are instantiated right after the related code element (e.g. a method declaration) is visited. These virtual shadows act almost the same as other shadows in the matching process, except that they are not matched against the standard shadow mungers, such as advices, declares etc.  19  Signature Relaxers  Relaxer AnnotationRelaxer Modifier Relaxer Ret urnTy p eRelaxer  DeclaringTypeRelaxer  NameRelaxer ParamsRelaxer ThrowRelaxer ArgsRelaxer Handler Relaxer Pointcut Relaxers ThisOrTargetRelaxer WithinRelaxer  Condition  Table 3.1: Relaxers  Relax Operation change to * change to * change to *  , if the return type pattern is primitive type ( i n t , void,...) if the return type pattern can be resolved to a change to its super type single type add + if the return type pattern has no + add + if the declaring type pattern has no + if the pointcut is not about constructors and can change to its super type be resolved to a single type if the declaring type does not match types in all add *. . at the beginning packages add * at the beginning if the name pattern does not start with * ' add * at the end if the name pattern does not end with * change to . . change to * drop add + if the exception type pattern has no + if the exception type pattern can be resolved to a change to its super type single type drop add + if the type pattern has no +  Chapter 3. Computing Almost Matched Join Points  3.3  Related Work  We next discuss how our algorithm is different from some existing work. A n balagan and Xie propose boundary join points [5] in the context of AspectJ pointcut testing. Boundary join points are join points that are not matched by the pointcut but have close textual representations to the matched ones. Our algorithm for computing almost matched join point shadows is more sophisticated. Firstly, in contrast to boundary join points, pointcut relaxation, uses important structural information from the code base to inform relaxation. For example we consider two classes as similar if they are related through inheritance whereas boundary join points only considers textual similarity. Secondly, pointcut relaxation attaches a different significance to different parts of a pointcut. For example a variation in the name of a method signature is considered more significant than a variation in the return type. In contrast boundary join points treat all parts of a pointcut as having the.same significance. Thirdly, we propose the notion of virtual join point shadows which allows showing information about almost matched join points that do not exist, in the current code base, but are likely to occur in future versions of the code. Anbalagan and Xie also propose mutant pointcuts [6]. The way to generate mutant pointcuts is similar to our pointcut relaxation in that the original pointcuts are slightly modified. However, this technique is used for verifying if a test suite is able to detect common errors in pointcuts, rather than computing almost matched join points information that helps developers write pointcuts.  3.4  Summary  In this chapter, we presented our algorithm, a technique called pointcut relaxation, to compute almost matched join point shadows. We also proposed virtual join point shadows to handle the possible evolution of the code base. Finally, we discussed how our algorithms are different from Anbalagan and Xie's work on boundary join point and mutant pointcuts.  21  Chapter 4  Pointcut Explanation In order to explain why a pointcut does not match (or does match) a join point, we present two kinds of explanations in PointcutDoctor. The first is a color-coded highlighting of a pointcut expression that shows which parts of the pointcut expression are responsible for the non-match(or match). The second is a text message explaining why a highlighted part matches (or does not match) the given join point. In the following two sections, we will discuss the algorithms that compute these two kinds of explanation.  4.1  Computing Color-coded Highlighting Explanation  Intuitively, if a pointcut unintentionally does not match a join point, this is because there is something wrong with one or more parts of the pointcut, i.e. these parts do not match (or do match ) the given join point. PointcutDoctor highlights these responsible parts in the pointcut using a color indicating whether they match or not. In this section we present our algorithm to identify these responsible parts. First we show that any pointcut can be converted into a propositional formula, so that the following definitions and algorithms can be discussed using standard propositional logical notations. We then develop the key definitions and the algorithm to compute the explanation. Finally we discuss some variations of the given algorithm. 4  4.1.1  Converting Pointcuts into Propositional Formulas  Any pointcut can be converted into a propositional formula. First, any primitive pointcut can be converted into a propositional formula that has a conjunction of variables. Each variable corresponds to a fragment of the When a negated pointcut matches a join point, it could cause the entire pointcut not to match. 4  22  Chapter 4. Pointcut Explanation pointcut (e.g. the declaring type) and its value is determined by the given join point and the pointcut. Secondly, since any compound pointcut consists of primitive pointcuts connected by A(AND), V(OR) and/or -^(NOT) operators, we can recursively convert a compound pointcut into a propositional formula. For example, the pointcut c a l l (* Foo+. f 0 0 ( i n t , . . ) ) && t a r g e t (SubFoo) can be converted into u\ A it 2 A 113 A U4 A 1x5. where the variable u\,u$ represent the matching status of different parts of the pointcut for a given join point: • u\\ does the return type in the signature of the join point match the pattern *? . • U2: does the declaring type in the signature of the join point match the pattern F 0 0 + ?  • 113: does the name in the signature of the join point match the pattern foo?  • U 4 : does the arguments of the given join point match the pattern  (int,..)? • 115: does the target of the given join point match the pattern SubFoo? Notice that we convert each component of a pointcut into a unique variable. Each variable represents a fragment of the pointcut and is treated as an independent piece of the cause, even though intuitively these variables might not be independent. For example, in c a l l ( * Foo. foo ( i n t ) ) && a r g s . ( i n t ) , two distinct variables are introduced to represent the two occurrences of ( i n t ) in the pointcut. As a result when a join point does not have an ( i n t ) parameter lists both occurrences of ( i n t ) in the pointcut are considered as independent causes for the non-match. This results in the desired behavior for generating coloring explanations, i.e. each occurrence of ( i n t ) in the pointcut will be independently marked as responsible for the non-match and colored accordingly. 4.1.2  K e y Definitions  We can now present formal definitions to allow us to identify the responsible parts in a pointcut, that is, the parts of the pointcut that are responsible for a particular (non)match. We mainly use the terminologies and mathematical notations from [7]. 23  Chapter 4. Pointcut Explanation For the propositional formula L consisting of variables u\, ..., u and the logical operators A(AND),V(OR) and ->(NOT), we represent its interpretation / as a set of tuples: / = {(u\, z \ ) , ( u , z )}\ where Z{ € {T, F} and (ui,Zi) stands for assigning value Z{ to variable U{. L(I) denotes the truth value of L given the interpretation / . A subset of an interpretation is called a partial interpretation. We now define the following terms: n  n  n  D e f i n i t i o n 4.1.1. [sufficient falsifying condition] The partial interpretation P is a sufficient falsifying condition for L if and only if V interpretation I D I , it follows that L(I) = False p  D e f i n i t i o n 4.1.2. [ m i n i m a l sufficient falsifying condition] The partial interpretation I is a minimal sufficient falsifying condition for L if and only if both of the following conditions are met: p  1. I  p  is a sufficient falsifying condition for L  2. VP' C I , 3 an interpretation I D P' such that L(I) = True p  D e f i n i t i o n 4.1.3. [Lp] For the formula L and an interpretation I, we define Lp to be the set of all minimal sufficient falsifying conditions that are subsets of I. Similarly, we can define Lip to be the set of all minimal sufficient true conditions for L. Our tool uses the definitions of L and L to explain why a pointcut does not match (or does match) a given join point. They represent all the possible ways that cause a non-match (or match). We use the value in the assignment tuple to determine the color code for the part of the pointcut that corresponds to the respective variable. F  4.2  T  The Algorithm  We can use the definitions developed above to derive our explanation algorithm based on a recursive traversal of the given propositional formula. A l g o r i t h m 4.2.1. Let L denote a propositional formula. Let I an interpretation for that formula and V a boolean value. We inductively define  24  Chapter 4. Pointcut Explanation cause(L,I, V) by the-following equations: cause(M AN,I,T)  =cause(M,I,T)(£)cause(N,I,T);  (4.1)  cause(M A N, I, F) =cause(M, I, F) [j cause(N, I,F);  (4.2)  cause(M V N, I, T) =cause(M, I, T) | J cause(N, I, T);  (4.3)  cause(M V N, I, F) =cause(M, I,F)(£)  (4.4)  cause(^M,  cause(N, I, F);  I, T) =cause(M, I, F);  (4.5)  cause(-^M, I, F) =cause(M, I,T);  (4.6)  Where M and N denote propositional formulae, u denotes a propositional variable, and (^) is an operator similar to cartesian product such that for power sets A and B (set of sets), A^)B = {x[Jy \ x £ A,y £ B}, for example, {{a}, {b, c}} ®{{b}, {d}} = {{a, b}, {a, d}, {b, c}, {b, c, d}}. T h e o r e m 4.2.1. Let L be a propositional formula where every variable only occurs at most once. Let I be an interpretation for L. Algorithm 4-2.1 will compute Lp and L^, i.e. cause(L,I,True)=L and cause(L,I,False)=L . I  T  F  P r o o f : B y structural induction on the propositional formula. The majority of the proof is straightforward. The only interesting part of the proof is that, in order to prove each element in the set cause(M A N, I, False) is a minimal falsifying condition for MAN, we need to assume that in the propositional formula L every variable only occurs once. As discussed in Section 4.1.1 we can assume that this is so because of the way the formula is derived. (Base Case) When L is a single variable, that is L = u, if I = {(u,T)}, then trivially {(u,T)} is the only minimal sufficient true condition for L, so we have u = {{(u,T)}} according to the definition of up, and up — (j) since there is no minimal sufficient falsifying condition exists for L. On the other hand, according to Algorithm 4.2.1, cause(u, I,T) = {{(u, T)}} and cause(u, I,F) — <f>. So we have cause(u, I,T) = u , and cause(u,I,F) = u. Similarly, if / = { ( i t , F)}, we can prove cause(u, I, T) = u , and cause(u, I, l  T  !  T  F  !  T  25  Chapter 4. Pointcut Explanation  (Induction Step) Suppose M ,M-,N ,NF  are m i n i m a l sufficient fal-  F  sifying/true conditions for B o o l e a n formulas M a n d JV given t h e interpret a t i o n / , a n d the following hold: • cause(M,  I, T) — M-  • cause(M,  I, F) = M £  • cause(N,  I, T) = N  • cause{N,  I,F) = N  T  F  . W e need to prove: 1. cause(M  A N, I, T) = (M A N)  2. cause(M  A N, J, F) = ( M A N)  3. cause{M  V N, I, T) = (M V N)  4. cause(M  V N, I, F) = (M V N)  T  F  T  F  5. cause(->M,I,T) 6. cause(-iM,  =  (-iM)!  r  I, F) = (->M)  F  A c c o r d i n g to A l g o r i t h m 4.2.1 a n d the i n d u c t i o n hypothesis, the proof of the above is equivalent t o the proof of: (M A N)* =M  l  T  T  ( g ) Ni  (4.9)  {M AN) =M \jN  (4.10)  (MV  (4.11)  F  F  F  Ny =M±\jN± T  ( M V AT)p =Aff ( g ) N f  (4.12)  (-iM)r =Af£  (4.13)  (-iM)f = M f  (4.14)  T o avoid redundancy, we only prove (4.10), (4.12) a n d (4.13). T h e other three equations c a n be proved i n the same fashion. Let I  m  Let I  m  and I  n  be interpretations such that M(I ) m  a n d 1Z denote any element i n M  m F  — F a n d N(I ) = F. n  a n d N ^, that is, I 1  m  € M|,  m  and  /£ 6 J V > .  26  Chapter 4. Pointcut Explanation From Definition 4.1.3 we know that: I  D l £ and I Dl£  m  (4.15)  n  V7' C n  3 interpretation lf  n  D 7^ such that M ( / £ ) = T  (4.16)  Let V and 7^ be any subset of 7^ and l£ respectively. From (4.16), we know that we can find interpretations 7,^ and 7^ such that 7^ D I' and M(li)=T,I D / ; and iV(7,f) = T. P r o o f for (4.10) ( M A 7V)^ = M / , U N : m  m  s  n  F  • (Sufficient) Since M ( 7 ) = F, we have V7 D I D M ( 7 ) A JV(J) = M ( 7 ) A 7V(7) = F A iV(7) = F m  , (M A N)(I)  m  =  m  • (Minimal) We could select an 7 such that 7 D 7^ and N(I) =T. we have J D / ^ D 7^ and ( M A JV)(7) = Af A JV(J) = T.  So  That is, is a minimal sufficient falsifying condition for M AN. Similarly, we can prove l£ is also a minimal sufficient falsifying condition for M A N = F. Thus, ( M A N) = M {JN . P r o o f for (4.12) ( M V N) = M ® F  F  F  F  T  • (Sufficient) From (4.15), we know that 7 [ j 7 D I^\Jl£Since M ( 7 ) = F and N(I ) = F, we have V interpretation 7 D 7 ( J 7 3 /£ U , V AO (7) = M ( 7 ) V N(I ) = F. m  m  n  n  m  m  n  n  . (Minimal) Since M ( / £ ) = = T, let 7' = J L . U 4 , I = we have 7' c / £ (J l £ , 7 D 7' and ( M V N){I) = M ( / £ ) V N(I%) = T. That is, 7^ | J 7,f is a minimal sufficient falsifying condition for MvN. Since 7^ and l£ could be any element in M and A ^ ' respectively, according to the definition of the operator (g) (See Section 4.2), ( M V N) = Mp(g)N . P r o o f for (4.13) (->M)f = M / - : l  1  F  F  • (Sufficient) Since M(I ) m  F  = F , we have ( - . M ) ( J ) = ->M(7 ) = T. m  • (Minimal) Since M ( j £ > = T, we have ( n M ) ( ^ ) =  m  (/£) = F  So, 7,/^ is a minimal sufficient true condition for (->M). That is, ( - i M ) j . = (End of proof)  27  Chapter 4. Pointcut Explanation  4.3  A l g o r i t h m Variants  T h r e e - v a l u e V a r i a n t : In AspectJ, there is a notion of Maybe that represents the result of matching in case runtime determination is required. If we want to explain why a pointcut matching is evaluated as Maybe, we can define the cause similar to previous definitions of L and lJ . We can augment Algorithm 4.2.1 by adding: F  T  cause(M V N, I, Maybe) =(cause(M, I, Maybe) (^) cause(N,  I ,Maybe))\^ J  (cause(M, I, Maybe) (^) cause(N, I, True)) ( J (ca,use(M, I, True) (^) cause(N, I, Maybe)); cause(M V N, I, Maybe) =(cause(M, I, Maybe) (^) cause(N, I, Maybe)) [ J (cause(M, I, Maybe)  cause(N, I, False)) [J  (cause(M, I, False) (^) cause(N, I, Maybe)); cause(-iM,  I, Maybe) —cause(M, I, Maybe);  cause(u, I, Maybe) = ( y q>  M  o  ^ ) »  ^  &  otherwise  '  A p p r o x i m a t i o n V a r i a n t : The algorithm described in Theorem 4.2.1 not only finds the variables that are responsible for the non-match (or match), but also provides some structural information in the cause. For example, for L — u V (v A w) with the interpretation u — v — w — F, we have Lp = {{(u, F), (v, F)}, {(u, F), (w, F)}}. This result not only says u,v,w are all responsible variables", but also indicates " i t and v (or u and w) alone can sufficiently make L = F". However, this information introduces exponential time and space complexity to the algorithm. The complexity comes from the cartesian product operation involved in (1) and (4). u  In practice, we believe the information of responsible variables alone is adequate for users to diagnose the problems in their pointcuts. In order to improve the performance of PointcutDoctor, we chose to discard this structural information in the cause by replacing (1) with: cause(L A N, I, T) = cause  (L,I,T)\Jcause(N,I,T); 28  Chapter 4. Pointcut  Explanation  and replacing (4) w i t h :  cause(L V N, I, F) = cause  (L,I,F)\Jcause(N,I,F);  T h e modified a l g o r i t h m has linear c o m p l e x i t y i n the number of variables i n the formula, and still provides the responsible variables i n the results.  4.4  Computing Textual Explanation  T h e t e x t u a l e x p l a n a t i o n aims to provide explanations i n the context of the code base and educate users about language subtleties and best practices. S i m i l a r to our pointcut relaxation a l g o r i t h m (See 3.1), we use the results of our s t u d y of the aspectj-users m a i l i n g list, i n s t r u c t i o n a l books [17][10], and other web resources [4] as general guidelines to create a catalog of exp l a n a t i o n heuristics. T h e heuristic rules are categorized by the k i n d of pointcut components and the type of j o i n point. A heuristic rule consists of a group of conditions and a message to be shown for the user when these conditions are satisfied. T h e conditions describe the testing on the given j o i n point and the patterns i n the pointcut. T h e messages are customized by the i n f o r m a t i o n i n the code base, e.g. the actual declaring type of the given j o i n point. T h e r e are 35 rules implemented i n P o i n t c u t D o c t o r at the time of this w r i t i n g . Table 4.1 elaborates the heuristic rules to be used when the pointcut does not. m a t c h the j o i n point, and Table 4.2 presents the heuristic rules for matches. Table 4.4 explains the code used i n Table 4.1 and Table 4.2. Table 4.3 lists the actual messages being presented to the user w h e n the c o n d i t i o n is satisfied. For example, let's consider pointcut c a l l ( F o o .new(. . ) ) &&target(f oo) and j o i n point shadow c o n s t r u c t o r - c a l l (Foo .new()). T h e t a r g e t ( f o o ) sub-expression causes the pointcut not to m a t c h the j o i n point. Our t o o l w i l l produce the message M S G T a r g e t O : " C o n s t r u c t o r calls do not have target. Use the advice after(...) returning(...) to capture the object being created.". T h i s message is determined by looking up rows corresponding to t a r g e t pointcut i n Table 4.1, and then l o o k i n g up j o i n point k i n d c o n s t r u c t o r - c a l l i n the found rows.  29  Chapter 4. Pointcut Explanation Table 4.3: Explanation Messages Code MSGAnnoO MSGRTO MSGDTO  MSGDT1 MSGDT2  MSGDT3  MSGDT4  MSGDT5 MSGDT6  MSGDT7  MSGArgsO MSGArgsl MSGParamO  MSGThrowO  MSGThisO MSGTargetO MSGTargetl  )  Message Annotations are not inherited by default, though the method [methodName] is overridden in [jp.dt] The return type [jp.rt] is not matched even though it's a subtype of [ptn.rt]. Add a "+" to include subtypes of [ptn.rt] in the return type. Calls to constructors of [ptn.dt]'s subtypes (e.g. [jp.dt]) won't be matched. Use [ptn.dt]+ to include calls to constructors of its subtypes. Constructors of [ptn.dtj's subtypes (e.g. [jp.dt]) won't be matched. Use [ptn.dt]+ to include constructors of its subtypes. The declaring type of [private/static] methods has to be matched exactly by the pattern "[ptn.dt]", i.e. methods with the same signatures in subtypes are not matched. The method [methodSig] is not applicable to the type [ptn.dt], i.e. it is declared in [jp.dt] but not in [ptn.dt] or any of [ptn.dt]'s super types. Use [ptn.dt]+ to include all qualifying methods declared in its subtypes. Call pointcut only matches against the static target type, but the static target type of this call ([jp.dt]) is neither [ptn.dt] nor subtype of [ptn.dt]. Use [call(* set*(..))&&target(SubFoo)] to include the join point with the runtime target type being [ptn.dt]. [jp.dt] cannot be matched by pattern "[ptn.dt]" A "[jp.dt]" is not a "[ptn.dt]". Use [execution(* set*(..))&&this(SubFoo)] to include the join point arising here with the runtime type being [ptn.dt]. The declaring type is not matched because field [fieldName] is re-declared in class [jp.dt]. - Use [jp.dt] to pick this join point only, and [ptn.dt]+ to pick fields declared in [ptn.dtj's subtypes [ptn.param] does not match join points with [param-num] arguments [jp.param] cannot be matched by pattern [ptn.param]. Unlike args(...), the parameter pattern here only matches against the STATIC types of the join point's parameters, so the parameter types of this join point ([jp.param]) cannot be matched by the pattern [ptn.param] The method does not declare "throws [ptn.throws]". By Java convention, a method does not need to explicitly declare unchecked exceptions, though any method could throw such exceptions. There is no "this" in a static context Constructor calls don't have "target". Use the advice after(...) returning(...) to capture the object being created. Calls to static methods don't have "target". Continued on next page  30  Chapter 4. Pointcut Explanation Table 4.3 — continued from previous page Message The "target" could not be of type [ptn.type] This is not matched because method [jp.enclosingMethod] is declared in [declaring type of jp.enclosingMethod] but not in its super type [ptn.dt] MSGWithinO This is not matched because within only cares about static lexical scope. Use [ptn.type]+ to include join points within subtypes of Foo. MSGRefO [ptn.refName] does not match this join point, see the definition of [ptn.refName] for detailed reason. MSGHandlerO The handler pointcut does not implicitly match subtypes. Use handler([ptn.et]+) to include this join point. MSGO The [partType] of the given join point "[partValue]" cannot be matched by the pattern "[pattern]" IVLMSGDTO It is matched because: 1) The static target type of the call ([jp.dt]) is a subtype of [ptn.dt]; 2) method [methodSig] is [declared/inherited] in [ptn.dt] MJVISGParamO It is matched because: [paramT] is a subtype of [paramPattern] M.MSGWithincodeO The withincode pointcut matches method overrides, and [SubFoo.bar()] overrides method [Foo.bar()]. M.MSGArgsO [ptn.param] is a subtype of [jp.param]. Runtime test is needed because the runtime type of the argument could, but, not necessarily, be [ptn.param]. MJVISGArgsl [jp.param] is a subtype of [ptn.param], and the runtime type of the argument will always be of type [ptn.param]. MJVlSGHandlerO It is matched because [jp.param] is a subtype of [ptn.param] M.MSG0 Code MSGTarget2 MSGWithincodeO  4.5  Summary  In this chapter, we discussed the algorithms that computes two kinds of explanations about w h y a p o i n t c u t does not m a t c h (or does match) a j o i n point. T h e first is a color-coded highlighting of a pointcut expression that shows w h i c h parts of the pointcut expression are responsible for the nonmatch(or m a t c h ) . T h e second is a text message explaining w h y a highlighted part matches (or does not match) the given j o i n point. In the next chapter, we w i l l present a case study as the evaluation of the u t i l i t y of the i n f o r m a t i o n computed by our algorithms i n this chapter a n d C h a p t e r 3.  31  Table 4 . 1 : Not-match Explanation Heuristics Pattern Annotation Pattern Return type pattern Patterns in signature pattern Declaring type pattern  Parameter pattern Throws Pattern args this  target Primitive Pointcuts withincode within handler otherwise  Condition [jp.dt] isSubTypeOf [ptn.dt] & [jp.method] declared in both [jp.dt] and [ptn.dt] & [ptn.dt].method has annotation [ptn.anno]& [jp.method] hasn't annotation [ptn. anno] [jp.rt] isSubTypeOf [ptn.rt] & [ptn.rt] does not have "+"  • [jp.kind]=constructor-call & [jp.dt] isSubTypeOf [ptn.dt] [jp.kind]=constructor-execution/(pre)initialization & [jp.dt] isSubTypeOf [ptn.dt] .. [jp.method] is private or static & [jp.dt] isSub[jp .kind] =method-call TypeOf [ptn.dt] [jp.dt] isSubTypeOf [ptn.dt] & [jp.method] is de& clared in [jp.dt] but not in [ptn.dt] [ptn.dt] isSubTypeOf [jp.dt] otherwise [jp.method] is private or static & [jp.dt] isSub[jp.kind]=methodTypeOf [ptn.dt] execution [jp.dt] isSubTypeOf [ptn.dt] & [jp.method] de& clared in [jp.dt] but not in [ptn.dt] [ptn.dt] isSubTypeOf [jp.dt] otherwise [jp.kind]=get/set & [jp.dt] isSubTypeOf [ptn.dt] & [jp.field] is declared in both [jp.dt] and [ptn.dt] the number of [jp.args is not matched by [ptn.args] the number of [jp.args] is matched by [ptn.args] & one of [ptn.args] isSubTypeOf one of [jp.args] [jp.method] does not declare [ptn.et] & [ptn.et] is an unchecked Exception the number of [jp.args is not matched by [ptn.args] the number of [jp.args] is matched by [ptn.args] & [jp.argType] IsameOrSubTypeOf [ptn.argType] & [ptn.argType] IsameOrSubTypeOf [jp.argType] the join point is in static context [jp. kind] =constructor-call [jp.kind]=method-call & [jp.method] is static [jp.kind]=field get/set & [jp.field] is static [jp.kind]=initialization/preinitialization [jp.kind] =exception-handler [jp.enclosingClass] isSubTypeOf [ptn.dt] & [jp.enclosingMethod] is not declared in [ptn.dt] & [ptn.dt] does not have a "+" [jp.enclosingClass] isSubTypeOf [ptn.type] jjp.et] isSubTypeOf [ptn.et]  Message MSGAnnoO  MSGRTO  MSGDTO MSGDT1 MSGDT2 MSGDT3 MSGDT4 MSGDT5 MSGDT2 MSGDT3 MSGDT6 MSGDT5 MSGDT7 MSGArgsO MSGParamO MSGThrowO MSGArgsO MSGArgsl  .  MSGThisO MSGTargetO MSGTargetl MSGTarget2 MSGTarget3 MSGTarget4 • MSGWithincodeO MSGWithinO MSGHandlerO MSGO  Table 4.2: Match Explanation Heuristics Pattern Patterns Declaring in sigtype nature pattern pattern Parameter pattern withincode Primitive pointcuts args otherwise  Condition [jp.kind]=method-call & [jp.dt] isSubTypeOf [ptn.dt] & [jp.method] declared/inherited in [jp.dt] and [ptn.dt] [jp.kind]=method-execution & [jp.dt] isSubTypeOf [ptn.dt] & method declared in [ptn.dt] or its super type [jp.param] isSubTypeOf [ptn.param] & [ptn.param] includeSubtypes [jp.enclosingMethod] overrides [ptn.method] [ptn.param] isSubTypeOf [jp.param] [jp.param] isSubTypeOf [ptn.param]  Message MLMSGDTO M.MSGDT0 M_MSGParamO M_MSGWithincodeO MJvISGArgsO M_MSGArgsl M_MSG0  Chapter 4. Pointcut Explanation  Table 4.4: Conventions used in Table 4.1 and Table 4.2 [jp.dt]  [ptn.dt] [ptn. anno] [jp. method]  [ptn.rt] [j p. kind] [jp.field]  [jp.args] [ptn.args] [ptn.throws] [jp. enclosingClass] [ptn. type] [jp. et] [ptn.et]  The declaring type in the signature of the join point The declaring type pattern of. the signature in the pointcut The annotation pattern of the signature in the pointcut The corresponding method at the join point (for method execution and method call join point only) The return type pattern of the signature in the pointcut The kind of the join point The corresponding field at the join point (for field get/set join point only) The arguments at the join point The argument patter in the pointcut The throws pattern in the pointcut The enclosing class of the join point The type in within pointcut The exception type in the exception handler join point The exception type in the handler pointcut  34  Chapter 5  Evaluation We implemented an offline analysis tool that generates a comprehensive report about all pointcuts in a given code base. Using this tool, we were able to find several real problems in existing, medium sized AspectJ code base. This supports our first claim of our thesis that the information computed by our algorithm can help a developer find problems in her pointcuts. The report generated by our tool consists of almost matched and matched join point shadow information for all pointcuts in the code base, and the corresponding textual explanation for each listed join point shadow. A sample of the report is shown in Figure 5.1. The code bases we used in our case study are Aspect-oriented ORBacus[18] and Aspect-oriented jEdit [9]. Aspect-oriented ORBacus is an AspectJ refactoring of a C O R B A middleware consisting of 310 pointcuts, 1297 classes, and 122,110 lines of code. Aspect-oriented jEdit is an AspectJ refactoring of a mature text editor consisting of 354 pointcuts, 428 classes, and 35,890 lines of code. 5  6  5.1  Case Study Procedures  Prior to our case studies, we had no knowledge or experience with the selected code bases. We wanted to determine whether it is possible to discover bugs (i.e. unintended misses) in pointcuts by looking through the list of almost matched join point shadows and their corresponding explanations. We skipped finding bugs that result in unintended matches because A J D T already provides a list of matches and evaluation of the utility of such list is outside the scope of this thesis. First, we ran our tool against both code bases to generate the reports. Second, we read, through the reports to try to identify unintended misses. Since we were not the authors of the code and we did not directly know the intention of these pointcuts, we made assumptions based on the reports and 5 6  ORBacus: http://www.iona.com/ jEdit: http://www.jedit.org  35  Chapter 5. Evaluation  after(com.ooc.OBCDRBA.0RB_impl o r b _ i m p l , com.ooc.OB.Properties p r o p e r t i e s , S t r i n g key) r e t u r n i n g ( S t r i n g v a l u e ) : c a l l ( * c o m . o o c . O B . P r o p e r t i e s . g e t P r o p e r t y ( . . ) ) && t h i s ( o r b _ i m p l ) && a r g s ( k e y ) && t a r g e t ( p r o p e r t i e s ) ...\orbacus\src\aop\codeset\aspects\Codec.aj:42::1253 * almost matched (21): 1. ORBSupport: m e t h o d - c a l l ( J a v a . l a n g . S t r i n g J a v a . u t i l . P r o p e r t i e s . getProperty(j ava.lang.String)) Not matched because: - C a l l p o i n t c u t o n l y matches a g a i n s t t h e s t a t i c t a r g e t t y p e , b u t t h e s t a t i c t a r g e t type of t h i s c a l l ( J a v a . u t i l . P r o p e r t i e s ) i s n e i t h e r com.ooc.OB.Properties nor subtype of com.ooc.OB.Properties. Use c a l l ( * g e t P r o p e r t y ( . . ) ) & & t a r g e t ( c o m . o o c . O B . P r o p e r t i e s ) t o i n c l u d e the j o i n p o i n t w i t h i t s runtime t a r g e t t y p e com.ooc.OB.Properties. - The " t h i s " of t h e g i v e n j o i n p o i n t (ORBSupport o r i t s subtype) cannot be matched by t h e p a t t e r n "this(com.ooc.OBCORBA.0RB_impl)" * matched ( 3 ) : 1. 0RB_impl: m e t h o d - c a l l ( J a v a . l a n g . S t r i n g com.ooc.OB.Properties. getProperty(j ava.lang.String)) 2. 0RB_impl: m e t h o d - c a l l ( J a v a . l a n g . S t r i n g com.ooc.OB.Properties. getProperty(j ava.lang.String)) 3. ORB.impl: m e t h o d - c a l l ( J a v a . l a n g . S t r i n g com.ooc.OB.Properties. getProperty(j ava.lang.String))  Figure 5.1: A Sample of the Report Used in Case Study  36  Chapter 5. Evaluation quick investigations of the code base (e.g. we looked at whether a class is subclass of another, whether a m e t h o d is overridden i n a subclasses etc.) F i n a l l y , we sent the list of possible bugs to the authors of b o t h code bases seeking to determine the validity of those bugs. Out of the 310 a n d 354 pointcuts i n O R B a c u s a n d j E d i t code bases, there are respectively 56 a n d 71 pointcuts that have at least one almost matched j o i n point shadows. It took us roughly 2 hours to go t h r o u g h the O R B a c u s report, a n d 1.5 hours to go t h r o u g h the j E d i t report.  5.2  Results  Table 5.1 shows the numbers of potential bugs we identified , a n d those the original developers confirmed to be valid. In the table, the first two columns lists the type of the b u g a n d the code of the e x p l a n a t o r y message produced by our tool. A s for the b u g numbers, c o l u m n I refers to the numbers of bugs that were identified as potential bugs w h e n we investigated the report; c o l u m n R refers to the numbers of real bugs confirmed by the developers; c o l u m n V refers to the number of " v i r t u a l " bugs: the developers claimed that they were not bugs since the missed v i r t u a l a n d p o t e n t i a l j o i n points does not affect the correctness of the c u r r e n t code base, however, they agreed i n c l u d i n g the missing p o t e n t i a l j o i n points i n the pointcut w o u l d be better style. We next explain each bug type i n detail: d e c l a r i n g - t y p e - c a l l this error is caused by misunderstanding of the static semantics of c a l l pointcut: the declaring type i n c a l l p o i n t c u t only matches against the static type of the call target, not its runtime t y p e . However, developers often t h i n k of the runtime type w h e n they write pointcuts. For example, i n one of the code bases, 7  c a l l ( * com.ooc.OB.Properties.getProperty (..)) is used intending to capture calls to g e t P r o p e r t y m e t h o d for instances of com. ooc . OB.Properties only. Here, com. ooc. OB. P r o p e r t i e s is a sub-class of j a v a . u t i l . P r o p e r t i e s . T h i s p o i n t c u t does not m a t c h the j o i n point below (in the second statement):  j a v a . u t i l . P r o p e r t i e s props = new com.ooc.OB.Properties(); S t r i n g p = props.getProperty("key"); 7  This semantics applies to the declaring type of execution and withincode too.  37  Chapter 5. Evaluation  ORBacus B u g T y p e Message  I  C R  declaringtype-call  MSGDT4  2  2  paramnumnot-  MSGArgsO  13  2  V  jEdit C . I R V 3  3  3  1  1  -1  1  match paramtype-  MSGParamO  notmatch subtype-  MSGDTO  3  3  constructc rcall modifiernotmatch  MSGO  2  2  return-  MSGO  1  1  typenotmatch handler-  MSGHandlerO  1  1  9  3  subtype Total Table 5.1:  18  7  3  6  Messages Issued and N u m b e r of B u g s F o u n d i n Case S t u d y  (Lldentified, ,C:Confirmed, R : R e a l bugs, V : " V i r t u a l " bugs)  38  Chapter 5. Evaluation param-num-not-match The developer was unaware of some overloaded constructors/methods in the code base. Some expected join points are ruled out by either the parameter pattern or args pointcut because the number of parameters in the join point cannot be matched. Note that we found 13 potential bugs of this type but most of them are false positives. This is because most overloaded methods call each other, so it's the expected behavior to only match one "root" method in the pointcut. The "virtual" bugs in this category are mostly misses of virtual calls to overloaded constructors. param-type-not-match The join point is not matched because the type of one of the parameters cannot be matched. The developer wrote c a l K v o i d add*Listener(EventListener)) intending to match method-call(void JButton.addActionListener(ActionListener)). But it cannot be matched even though ActionListener is a subtype of EventListener. subtype-constructor-call If "+" is not used in the declaring type of c a l l pointcut, it will not match calls to the constructors of the declaring type's subtypes. A l l of the identified bugs are classified as virtual since the developer agreed including all subtypes might be better style, as we discussed earlier. modifler-not-match The developer was unaware of the different modifiers for some of the expected join points. return-type-not-match Similar to "modifier-not-match", the developer was not aware of the different return type. It seems that developers often ignore the difference in modifier and return type when they write pointcuts. handler-subtype Similar to the subtype-constructor-call case, handler pointcut does not match exception handlers with sub-exception types, if "+" is not used in the pointcut. The developer used handler(Throuable) hoping to capture all exception handlers. In summary, we believe that the result of this study is quite positive: Several real bugs and style problems were discovered in real code bases. Given the sizes of both code bases, our unfamiliarity with them, and the relatively short time we spent on interpreting the reports, we believe it demonstrates that the process of identifying problems is facilitated by the information available in the report. Anecdotally, even when an almost matched join point shadow is not intended to be matched, the information can still be useful, as one of the developers of the case study code bases said, "these warnings indeed make me think about whether it could be problematic for other subtypes.".  39  Chapter 5. Evaluation  5.3  Performance Impact  In our development environment (Intel Core2 Duo Processor 2.33GHz C P U , 2G memory, Windows X P Professional), it took 50 seconds and 68 seconds for our tool to generate the reports for the Aspect-oriented jEdit and ORBacus code base, respectively. The memory usage of the javaw.exe process is 350M and 397M bytes for the two code bases. Compared to the numbers with the unmodified AspectJ compiler(20 seconds/250M and 30 seconds/290M), these numbers indicate that our extension to AspectJ compiler introduces performance overhead. We believe the running time overhead is caused by the large number of relaxed pointcuts being tested in the matching process. When a compound pointcut with many primitive pointcuts connected by I | and kk gets relaxed, potentially a large number of duplication will be produced by the D N F conversion (see Section 3.1.1). The memory usage overhead is because we produce extra helper objects in the process of pointcut relaxation and explanation, compared to the unmodified AspectJ compiler.  5.4  Summary  In this chapter, we presented the result of our case study in order to validate the usefulness of the information produced by the algorithms presented in this thesis. Based on this result, we believe that the information computed by our algorithms can help a developer find problems in her pointcuts. This supports our first claim in this thesis. We also evaluated and analyzed the performance impact of our algorithms.  40  Chapter 6  Limitations and Future Work In this chapter we discuss some of the limitations of our algorithms, of their current implementation and of the evaluation presented in this thesis. We also present some ideas on how these could lead to future work.  6.1  Limitation of Implementation  A limitation of our current implementation of pointcut relaxation is its performance overhead compared to the standard AspectJ compiler. It should be noted that performance was not the focus of this thesis. We rather focused on providing information that helps developers to diagnose and fix problems with their pointcuts. Having established that the information our algorithms compute is useful, future work could focus on more efficient implementations. For example, the run-time overhead could be reduced by optimizing the preprocessing and relaxation algorithms to produce fewer relaxed pointcuts. The memory usage would also be improved by this optimization because fewer helper objects would be generated. Another limitation of the current implementation is that it relies on a fixed set of heuristics. Our evaluation shows that the current set of heuristics provides useful results. However we believe that they can still be improved and extended. This is a possible topic for future work. A third limitation of the current implementation presented is that we have not directly considered cf low, cf lowbelow and i f pointcuts. However, a user can indeed write the enclosed pointcut in cf low or cf lowbelow as a named pointcut, and have it explained by our tool. The direct support for these three pointcuts is a possible topic for future work.  6.2  Limitation of Evaluation  The evaluation presented in this thesis focused on determining whether information on almost matched join points and explanations of why they do or do not match is useful to find problems in pointcut expressions. We decided to  41  Chapter 6. Limitations and Future Work separate the question of whether this information is useful by itself from the question of how to present it in the I D E . Therefore, we used an offline report to perform our case-studies rather than the PointcutDoctor I D E . Because of the "raw" presentation format used, we believe the results of the case studies are relatively independent from presentation issues. Presently, we have not directly evaluated the design of the PointcutDoctor G U I . Nevertheless, we have faith in our G U I design because a) the presented information has been shown to be independently useful and b) our G U I design naturally extends the state-of-the-practice A J D T UI. Future work could focus independently on the G U I design and determine whether it is effective in making this useful information readily available to developers. Another limitation of the evaluation is that we did not separately evaluate the utility of the explanations versus the lists of matches and almost matches. What our results show is that in combination this information can be useful to find problems with pointcuts. However, our results provide no solid conclusions about the usefulness of these types of information considered in isolation.  6.3  Summary  In this chapter, we discussed some of the limitations of our algorithms, of their current implementation and of the evaluation presented in this thesis. We also presented some ideas on how these could lead to future work.  42  Chapter 7  Conclusion In this thesis, we proposed to help AspectJ developers diagnose and fix potential problems in their pointcuts by extending existing I D E to provide two kinds of information: almost matched join point shadows and explanation, on why a pointcut matches (or does not match) a given join point. We presented our algorithms to compute this information. We elaborated the heuristics used in our algorithms extracted from our previous empirical study on Aspectj user mailing list and other resources. We make two claims in this thesis. First, we claim that the information computed by our algorithms can help a developer find problems in her pointcuts. Second, we claim that this information can be added into existing I D E tools in a clean and logical way. To prove our first claim, we evaluated the utility of the information produced by our algorithm by conducting case studies on two existing mediumsized AspectJ code bases. B y going through the report generated by our tool, we were able to identify real problems in the code bases in a couple of hours, despite that we did not have any previous knowledge about the code bases before the study. Based on the results of the case study, we believe that the information computed by our algorithms can help a developer find problems in her pointcuts. To prove our second claim, we developed an Eclipse plugin called PointcutDoctor. PointcutDoctor is a natural extension of A J D T that provides developers easy access to the information discussed above from within their familiar development environment.  43  Bibliography [1] Ajdt: Aspectj development tools, http://www.eclipse.org/ajdt. [2] Aspectj users mailing list archive, http://dev.eclipse.org/mhonarc/lists/aspectjusers/maillist.html. [3] Eclipse - an open development platform, http://www.eclipse.org. [4] Ibm developerworks: Aop@work. http://www128.ibm.com/developerworks/views/java/libraryview.jsp ?search by=AOP@work. [5] Prasanth Anbalagan and Tao Xie. Apte: automated pointcut testing for aspectj programs. In WTAOP '06: Proceedings of the 2nd workshop on Testing aspect-oriented programs, pages 27-32, New York, N Y , U S A , 2006. A C M Press. [6] Prasanth Anbalagan and Tao Xie. Efficient mutant generation for mutation testing of pointcuts in aspect-oriented programs. In Proceedings of the 2nd Workshop on Mutation Analysis (MUTATION 2006), pages 51-56, November 2006. [7] M . Ben-Ari. Mathematical logic for computer science. Prentice-Hall, . Inc., Upper Saddle River, N J , 1993. [8] C. Clifton and G . Leavens. Obliviousness, modular reasoning, and the behavioral subtyping analogy. In Iowa State University Technical Re- . . port, TR 03-15. [9] J . Collins-Unruh and G . Murphy. Aspect-oriented jedit. unpublished. [10] Adrian Colyer, Andy Clement, George Harley, and Matthew Webster. Eclipse AspectJ: Aspect-Oriented Programming with AspectJ and the . Eclipse AspectJ development tools. Addison-Wesley, 2004. [11] R. Firman and D . Friedman. Aspect-oriented programming is quantification and obliviousness. In Workshop on Advanced Separation of Concerns, OOPSLA 2000, October 2000. 44  Bibliography [12] Robert Filman. What is aspect-oriented programming, revisited. In Workshop on Advanced Separation of Concerns, 15th European Conference on Object-Oriented Programming, June 2001. [13] Erik Hilsdale and Jim Hugunin. Advice weaving in aspectj. In AOSD '04'- Proceedings of the 3rd international conference on A sped-oriented software development, pages 26-35, New York, N Y , U S A , 2004. A C M Press. [14] Gregor Kiczales, Erik Hilsdale, Jim Hugunin, M i k Kersten, Jeffrey Palm, and William G . Griswold. A n overview, of AspectJ. Lecture Notes in Computer Science, 2072:327-355, 2001. [15] Gregor Kiczales, John Lamping, Anurag Menhdhekar, Chris Maeda, Cristina Lopes, Jean-Marc Loingtier, and John Irwin. Aspect-oriented programming. In Mehmet Ak§it and Satoshi Matsuoka, editors, Proceedings European Conference on Object-Oriented Programming, volume 1241, pages 220-242. Springer-Verlag, Berlin, Heidelberg, and New York, 1997. [16] Gregor Kiczales and M i r a Mezini. Aspect-oriented programming and modular reasoning. In ICSE '05: Proceedings of the 27th international conference on Software engineering, pages 49-58, New York, N Y , .USA, 2005. A C M Press. [17] Ramnivas Laddad. AspectJ in Action: Practical Aspect-Oriented Programming. Manning Publications Co., Greenwich, C T , U S A , 2003. [18] Charles Zhang and Hans-Arno. Jacobsen. Quantifying aspects in middleware platforms. In AOSD '03: Proceedings of the 2nd international conference on A sped-oriented software development, pages 130-139, New York, N Y , U S A , 2003. A C M Press.  45  

Cite

Citation Scheme:

        

Citations by CSL (citeproc-js)

Usage Statistics

Share

Embed

Customize your widget with the following options, then copy and paste the code below into the HTML of your page to embed this item in your website.
                        
                            <div id="ubcOpenCollectionsWidgetDisplay">
                            <script id="ubcOpenCollectionsWidget"
                            src="{[{embed.src}]}"
                            data-item="{[{embed.item}]}"
                            data-collection="{[{embed.collection}]}"
                            data-metadata="{[{embed.showMetadata}]}"
                            data-width="{[{embed.width}]}"
                            async >
                            </script>
                            </div>
                        
                    
IIIF logo Our image viewer uses the IIIF 2.0 standard. To load this item in other compatible viewers, use this url:
http://iiif.library.ubc.ca/presentation/dsp.831.1-0052055/manifest

Comment

Related Items