• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Advice weaving in AspectJ
 

Advice weaving in AspectJ

on

  • 6,661 views

One possible approach of AOP is to weave advice into existing classes. This approach is taken by AspectJ. In this presentation we explore how this is done, and look at some alternatives as well.

One possible approach of AOP is to weave advice into existing classes. This approach is taken by AspectJ. In this presentation we explore how this is done, and look at some alternatives as well.

Statistics

Views

Total Views
6,661
Views on SlideShare
6,641
Embed Views
20

Actions

Likes
2
Downloads
87
Comments
0

1 Embed 20

http://www.slideshare.net 20

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Advice weaving in AspectJ Advice weaving in AspectJ Presentation Transcript

    • Advice weaving in AspectJ Advice weaving in AspectJ AOP Seminar - Session 7 Sander Mak Center for Software Technology, Universiteit Utrecht December 6, 2006 Center for Software Technology Sander Mak
    • Advice weaving in AspectJ Outline Introduction 1 JVM bytecode 2 Weaving in AspectJ 3 Weaving in Aspect Bench 4 Semantics of static pointcuts 5 Conclusion 6 Questions 7 Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Introduction AspectJ Most widely used aspect language and compiler for Java Eclipse community project Large contributions by IBM Goals: Create a stable aspect language for Java 1 Provide a production quality compiler 2 Create supporting tools for AO development 3 Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Introduction Paper: Advice Weaving in AspectJ By Erik Hilsdale and Jim Hugunin (both AspectJ developers) Based on 1.1 (current branch: 1.5) almost everything still applicable except for performance indicators Paper’s focus: finding pointcuts, weaving advice in ajc Additionally, benchmarks are performed Most recent implementation paper from AspectJ team Why focus on the the weaver? It’s complex: 82/131 of open AspectJ bugreports are weaver-related ... ... but it’s interesting! Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > JVM bytecode Bytecode class contents A compiled Java class can be divided into 2 sections: Constant pool Bytecode Class name Instructions Method names Per method Method signatures (e.g. I(IL)) Stack based Constants Weakly typed (checks are enforced though) Field references Fully qualified names Arbitrary attributes Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > JVM bytecode JVM Overview Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > JVM bytecode Stackframes Every currently executing method has a frame on the stack: Local variable store Unique indices Operand stack for expression evaluation Pointer to constant pool Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > JVM bytecode Example Test.java public class Test implements SomeInterface { public void main(String[] args){ int i; i = 1; String s = args[0]; int j = 1 + i; } } Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > JVM bytecode Example Bytecode Test.java public class Test implements SomeInterface { public void main(String[] args){ int i; i = 1; String s = args[0]; int j = 1 + i; } } Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ Terminology Before moving on, let’s revisit some of the AOP terms: pointcut Pattern describing events based on matching static code and doing dynamic checks joinpoint Actual intercepted runtime events (point in execution graph) shadow Region of code belonging to a joinpoint (statically determinable) advice Additional code executed at joinpoint Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ Implementing AOP In general, there are several options to implement the AOP paradigm: Combine (weave) advice at compile time with original program Restricts joinpoint model considerably Or needs to be supplemented with runtime system Modify runtime environment to support joinpoint model dynamically For example: add hooks to virtual machine Complete freedom of joinpoint model, but at high costs Some languages: implement using reflection As above, probably even worse Load-time weaving, e.g. using custom ClassLoaders in Java Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ ajc architecture Parse Java+AspectJ 1 Compile advice into 2 methods (and annotate) Annotate shadows based 3 on pointcut declarations Weave advice 4 Emit Java bytecode 5 Various optimizations left out Java 1.5 Annotations can replace front-end Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ Compiling advice Body of advice is put in a method Environment information is added to signature Parameters to the advice JoinPoint and JoinPoint.StaticPart Optimization: leave either one out, or replace with StaticPart Contents of environment pruned for optimization Reflective information is expensive as it involves: Object creation Casting arrays of arguments (can have complexity O(n)) Special case: around advice with proceed calls ProceedJoinPoint holds AroundClosure Contains information to resume normal operation from within advice Implemented as Object-array containing surrounding free variables Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ Finding shadows To weave advice, we must locate the execution points in code: shadows Match pointcut of each advice to joinpoints (O(s·a)) On match: modify bytecode to call advice Calling advice Create necessary context 1 Possibly store arguments 2 Add: 3 invokestatic [A.aspectOf] invokevirtual [ajc$pointcut$advicename] Context sensitive pointcuts leave dynamic residue Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ FastMatchTM Time complexity can get out of hand. Therefore ajc should optimize: Leveraging information from a classes’ constant pool: Class name Fully qualified classname, to check within pointcut Method names check for matching pointcuts Method signatures find applicable methods without scanning whole class Field references check for matching set/get pointcuts In 1.1 only the first optimization is applied Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ Question: Gerbo Could you elaborate a bit on the fastmatch pass? It seems quite vital for compilation efficiency, but the authors go over it quite fast. Also -two years after the paper-, did they implement fastmatch for more PCDs than within, and did they implement the optimization they mention? And if so, does compilation perform significantly better? Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ Question: Gerbo Could you elaborate a bit on the fastmatch pass? It seems quite vital forQuestion of Nabil as well: the authors go over it quite fast. Also compilation efficiency, but Why isnt fastmatch used to implement other PCDs such Construc- -two years after the paper-, did they implement fastmatch for more PCDs than within, and did they informationthe optimization they these tor/method execution? All the implement needed for to match mention? And if so, present in the constant pool information. example PCDs is does compilation perform significantly better? Leaving out FastMatch for within gave 256% increase in compiletime It would be natural to add others: hard to find out what’s really done I emailed the authors, so far no response :-( Bugzilla does mention ’some’ FastMatch additions but 1.2 was already twice as fast, 1.5 even better Other optimization (kinded joinpoints) has been implemented Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ Question: Gerbo Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ Shadow mungers to munge - The Jargon File muhnj [derogatory] 1. To imperfectly transform information. 2. A comprehensive rewrite of a routine, datastructure or the whole program. 3. To modify data in some way the speaker doesn’t need to go into right now or cannot describe succinctly (compare mumble) A shadow munger describes a translation strategy for every type of advice. Paper gives informal descriptions And some examples of the 2-step process: Expose context 1 Inject desired behavior 2 Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ Shadow mungers Transform shadow within boundary Ensures compositionality Apply in inverse precedence order Precedence rules are complex, and are user-definable as of 1.5 Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ Shadow mungers Transform returns to unconditional jump Add call to advice at result label Of course: add correct return Alternative: inline advice call before each return statement Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ Dynamic Residue Not everything can be determined at compile time: Polymorphism public void interceptMe(Object a) {..} -- aspect: before(): execution(* interceptMe(String)) {..} Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ Dynamic Residue Not everything can be determined at compile time: Polymorphism public void interceptMe(Object a) {..} -- aspect: Problem: before(): execution(* interceptMe(String)) {..} interceptMe(Object a) matches, but: Runtime check necessary to see whether the object is of type String: instanceof [String] ifeq jump to label ..advice.. jump to label: ..normal code.. If Object were Integer, we can statically decide against the advice Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ Dynamic Residue Not everything can be determined at compile time: Polymorphism public void interceptMe(Object a) {..} -- aspect: before(): execution(* interceptMe(String)) {..} If pointcut Every If check results in dynamic checking code Partial evaluation could improve this (at higher costs) Example: if(Tracing.level==1) Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ Dynamic Residue Not everything can be determined at compile time: Polymorphism public void interceptMe(Object a) {..} -- aspect: before(): execution(* interceptMe(String)) {..} If pointcut Every If check results in dynamic checking code Partial evaluation could improve this (at higher costs) Example: if(Tracing.level==1) this/target Both could leave dynamic instanceof residue Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ Dynamic Residue cflow is notoriously expensive: ajc has to insert code that manipulates a call-stack at runtime entry/exit recorded on stack in ThreadLocal variable advice can inspect stack to check applicability of cflow pointcut in a joinpoint this administration brings much overhead Stackless implementation using sophisticated guards/counters is in progress (OOPSLA paper 2006) Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ Drawbacks of ajc Due to implementation of weaving there are some operation restrictions: End of exception handler is not explicit in bytecode: no after or around advice possible Only bytecode ’controlled’ by ajc can be woven: declare parents : String implements MyInterface will not work Reflective calls are not intercepted (semantically you could argue this is bad) Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ Drawbacks of ajc Due to implementation of weaving there are some operation restrictions: End of exception handler is not explicit in bytecode: no after or around advice possible Only bytecode ’controlled’ by ajc can be woven: declare parents : String implements MyInterface will not work Reflective calls are not intercepted (semantically you could argue this is bad) Java source/bytecode mismatch translated by Java compiler as: String foo = s + quot;aquot;; String foo = s.append(quot;aquot;); aspect: before() : execution(* append(*)) {..} Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in AspectJ Drawbacks of ajc Dependencies: A heavily customized version of ecj also the reason why it takes so long to adapt ajc to new Eclipse releases changes are not trivial: at least 44 Java source files involved parser is ’hacked’ to handle pointcuts Apache BCEL modified version is used BCEL is no longer maintained, so ajc maintains it (as of june this year this might have changed) Somewhat vague semantics (shadow mungers) In general: ad-hoc, non-extensible, but fast implementation Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in Aspect Bench Introduction Based on: abc: an extensible AspectJ compiler P. Avgustinov, O. de Moor The Aspect Bench Compiler is a research compiler with the following goals: clean seperation of front-end/back-end extensible typesystem, matcher and weaver painless code generation allow for pointcut selection based on semantics instead of naming Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in Aspect Bench Architecture Front-end: Polyglot Extensible parser and AST representation Syntax can be extended by defining modifications externally Built to be extended Back-end: Soot Intermediate language: Jimple Typed, stackless bytecode representation Bytecode generation Bytecode analysis and optimization All used in standard, non-modified way Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in Aspect Bench Bytecode vs. Jimple weaving Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in Aspect Bench Weaving Is generally much easier to specify in Jimple: Implicit execution stack is handled by stackless representation Optimization largely done by Soot, can be removed from translation Type information available everywhere Defensive copying of context by ajc is avoided, resulting in better performing code Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Weaving in Aspect Bench Extensions All extension can be made without modifying the existing AspectJ implementation Examples that are implemented: Private pointcut vars Variables scoped over pointcut only Cast pointcut Intercept typecasts Global pointcuts e.g. global : * : !within(HiddenClass) AspectJ still compiles faster, but generates less optimized code Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Semantics of static pointcuts Introduction Based on: Semantics of Static Pointcuts in AspectJ P. Avgustinov et al. Fundamental research on pointcuts: extendability formalization Submitted to POPL 2007 Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Semantics of static pointcuts Why? Reasons to study a formal semantics for pointcuts: Observation Point Cut Designators (PCD) form a language of their own; and it is already very expressive Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Semantics of static pointcuts Why? Reasons to study a formal semantics for pointcuts: Observation Point Cut Designators (PCD) form a language of their own; and it is already very expressive focus of research has been: semantics of advice or semantics of ’easy’ pointcut language Lots of subtleties and corner-cases Not desirable to depend on implementation (AspectJ) for specification A formal semantics gives baseline to evaluate and improve implementations Complexity is a continuing source of serious bugs in AspectJ Gives foundation to discussion of language extensions I will try to give the flavor of the paper Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Semantics of static pointcuts Approach Translate surface language (AspectJ+PCD) to core language Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Semantics of static pointcuts Approach Straightforward translation to relational representation of program (label insertion) Labels roughly correspond with boundaries of shadows Interesting part: how to translate the static pointcuts to sets of labels? Also: how do we know this translation is sound? Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Semantics of static pointcuts Datalog Pointcuts are rewritten to Datalog: A safe subset of Prolog (logic language based on facts and relations) Properties of Datalog: Creation of datastructures not possible Clear and straightforward semantics More efficient than Prolog Translation using term rewriting (Stratego) Result of translated Datalog querie is the set of labels for pointcut Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Semantics of static pointcuts Executable specification Datalog can be interpreted... .. by mapping to SQL! So the queries can be executed Typically 4 times slower than ajc Gain: direct correspondence between semantics and implementation And: you could write Datalog queries directly Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Conclusion Concluding remarks The weaver of ajc is complex Much can be gained using static analysis while weaving Current version of AspectJ is already much improved An alternative for ajc is abc, though it has different properties A thorough description of pointcuts has been made outside of the AspectJ project Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Wouter What would be the reason they chose to compile both the plain Java and the aspect first to bytecode and then weave it? Why not instead weave the aspect source code (after translation to plain Java) directly into the Java source code and then compile it. Probable advantages: This is easier to implement I think This does not depend on (maybe changing) bytecode expressions You can actually see what happens, this can be handy when learning AspectJ You will be able to see the actual produced code, this might not be very nice code, but It could definitely help when debugging With all the code available at the same time the Java compiler might be able to do more optimizations Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Wouter Other reasons pro: ’Even if you are generating perfectly legal bytecodes, straying too far from the javac path can uncover bugs in VMs.’ If weaving source code, javac will save you from this You can do more: Begin and end of exception handler available Source location reported more accurately Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Wouter Other reasons pro: ’Even if you are generating perfectly legal bytecodes, straying too far from the javac path can uncover bugs in VMs.’ If weaving source code, javac will save you from this You can do more: Begin and end of exception handler available Source location reported more accurately Reasons con: Source is not always available Temptation to change generated code is big Not possible to do weaving at loadtime Analysis (munging!) much easier (no need to replicate javac’s name-resolution, type system etc.) Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Wouter Other reasons pro: ’Even if you are generating perfectly legal bytecodes, straying too far from the javac path can uncover bugs in VMs.’ If weaving source code, javac will save you from this You can do more: Begin and end of exception handler available AspectJSource location reported more accurately AspectJ moved from source weaving, in the early days, to bytecode Reasons con: weaving nowadays. Source is not always available Mostly due to to change generated code is big Temptation the analysis argument. In Not opinion, abcdo weaving theloadtime my possible to has found at right middle ground Analysis (munging!) much easier (no need to replicate javac’s name-resolution, type system etc.) Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Elmar The authors say that ’AspectJ’s implementations have used every form of transformation imaginable for a Java program’. But they don’t discuss the pro’s and con’s of the different transformation and why AspectJ is now a bytecode transformer. What do you think is the reason that AspectJ is now constructed as a bytecode transformer as apposed to a Java transformer? Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Elmar The authors say that ’AspectJ’s implementations have used every form of transformation imaginable for a Java program’. But they don’t discuss the pro’s and con’s of the different transformation and why AspectJ is now a bytecode transformer. What do you think is the reason that AspectJ is now constructed as a bytecode transformer as apposed to a Java transformer? As said: ease of analysis has been decisive factor Performance might have been also (esp. with new FastMatch) Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Jinfeng If a pointcut captures a good many calls in an advice, when the aspect is woven into the application, the size of the class file increases many times dramatically. In that case, running this application on your server may incur an OutOfMemoryError. So do you have any idea/experience to avoid/reduce this problem? Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Jinfeng If a pointcut captures a good many calls in an advice, when the aspect is woven into the application, the size of the class file increases many times dramatically. In that case, running this application on your server may incur an OutOfMemoryError. So do you have any idea/experience to avoid/reduce this problem? Not really a problem fundamental to AOP (handcoded would result in comparable codebase) Weaving in ajc results mostly in calls to advice Modest overhead Inlining would be more problematic Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Nabil The paper mentions that adding a static test (‘static field enabled‘) to the pointcut ‘traced‘ increases the performance of the code and makes even faster than the hand-coded version. Could you explain how this is possible? Because I would expect the performance to be same or reduced when an extra test is added to the pointcut. Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Nabil The paper mentions that adding a static test (‘static field enabled‘) to the pointcut ‘traced‘ increases the performance of the code and makes even faster than the hand-coded version. Could you explain how this is possible? Because I would expect the performance to be same or reduced when an extra test is added to the pointcut. Corresponding pointcut/advice: static boolean enabled; pointcut traced() = execution(* *(..)) && if (enabled) && if (log.isLoggable(Level.FINER)) ; before(): traced() { Signature s = thisJoinPointStaticPart.getSignature(); log.entering(s.getDeclaringType().getName(), s.getname()); } Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Nabil Hand-coded does not mean that static check of enabled is added. Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Nabil Corresponding pointcut/advice: pointcut traced() = execution(* *(..)) && if (enabled) && if (log.isLoggable(Level.FINER)) ; && is short-circuit (or lazy) Static field lookup and boolean comparison: very cheap Prevents call to isLoggable, that requires Lookup of Level.FINER Pushing it on the stack Resolving log (push on the stack invokevirtual method call (new stackframe created) All in all, this is only faster because hand-coded code was not adapted Would have involved changing 7700 locations: hence we saw a cross-cutting optimization! Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Niels I tried to compile an aspect program and make an executable Jar, it seems that it is possible to run the Jar without referencing the AspectJ package, but you will get 1 exception over and over (probably when using functions which use the aspect classes): Exception in thread ... java.lang.NoClassDefFoundError: org/aspectj/lang/NoAspectBoundException The developers of AspectJ did a pretty good job on allowing you to create programs without the need of the AspectJ library when you distribute it, what could be the reason for them to depend on this 1 class? Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Niels Actually, there are a lot more dependencies (depending on features used): AroundClosure and its machinery CFlowStack for bookkeeping of cflow pointcuts all types involved with thisJoinPoint Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Niels Actually, there are a lot more dependencies (depending on features used): AroundClosure and its machinery CFlowStack for bookkeeping of cflow pointcuts all types involved with thisJoinPoint Matt Chapman (AspectJ developer) on this matter: Yes, aspects are woven into class files, but there will be references to classes in the runtime library. This needs to be distributed with your software. This is unavoidable, .... you need the very small org.aspectj.runtime plugin. Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Niels For your specific problem: Exception in thread ... java.lang.NoClassDefFoundError: org/aspectj/lang/NoAspectBoundException ... what could be the reason for them to depend on this 1 class? We turn to the source: NoAspectBoundException.java /** * Thrown by the aspectOf special method on aspect types * when there is no aspect of that type currently bound. */ public class NoAspectBoundException extends RuntimeException { .. } Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Niels It looks like one of the previous problems (what is the ordering of aspects, because it does matter) comes from the fact that the original aspects aren’t preserved after compiling them (or aren’t used anymore): Code foo(new NonString()); pointcut fooOnString(String s) : call(* foo(s)); // Will not apply on the foo call, NonString is not a subclass of String Because, for now, this will never apply, this call won’t get a dynamic check to see if NonString is a subclass of String. Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Niels If you add an aspect later with this line: declare parents NonString extends String Now you might have needed the dynamic check, because now the first pointcut should apply to the function. Wouldn’t it be a good idea to keep the aspect, or remember where the aspect could have applied to allow these changes to do what they are supposed to (it might even be discussable if this is a change you would want) Center for Software Technology Sander Mak
    • Advice weaving in AspectJ > Questions Question: Niels If you add an aspect later with this line: declare parents NonString extends String Now you might have needed the dynamic check, because now the first pointcut should apply to the function. Wouldn’t it be a good idea to keep the aspect, or remember where the aspect could have applied to allow these changes to do what they are supposed to (it might even be discussable if this is a change you would want) As far as I could find out: inter-type aspects are applied before others Already in front-end of ajc, but I found little info Not sure if this also works with load-time weaving Center for Software Technology Sander Mak