Towards Reusable Components With Aspects [ICSE 2008]

50 %
50 %
Information about Towards Reusable Components With Aspects [ICSE 2008]

Published on May 19, 2008

Author: khoffman

Source: slideshare.net

Description

Does obliviousness increase overall modularity? This presents the results of an empirical study that focuses on the tradeoffs between obliviousness and modularity. The results may surprise you!

Towards Reusable Components with Aspects: An Empirical Study on Modularity and Obliviousness Kevin Hoffman / Patrick Eugster

Seen code that looks like this? (Carlo H. Séquin @ Berkeley) (speedcubing.com) (George W. Hart @ Stony Brook) (George W. Hart @ Stony Brook)

Roadmap  AOP with AspectJ  Challenges  Cooperative AOP with Explicit Join Points  Empirical Study  How obliviousness can be traded for increased modularity and reuse through Cooperative AOP  Potential pitfalls and guidelines

Cross-cutting Concerns (Thanks to AspectJ Dev Tools (AJDT) Visualization Eclipse Perspective)

Cross-cutting Concerns (Thanks to AspectJ Dev Tools (AJDT) Visualization Eclipse Perspective)

Real Crosscutting Concerns  Logging (canonical example)  Pooling / caching  Dependency injection  Policy / contract enforcement  Security  Transactions  Exception Handling

AOP & Crosscutting Concerns

Separation

Modularization

AOP Stratagems [Filman/Friedman’00]  Obliviousness  Increased modularity of base code and aspect code  Parallel and domain-specific development  Better post-mortem extendibility  Quantification (pattern matching)  Reduction in code size and duplicity  Higher level interaction between primary and cross- cutting concerns

AspectJ  AspectJ [Kiczales ’01]  Join point model  Structural points in ‘base code’  Quantification model (pointcuts)  Lexical patterns and type constraints  Dynamic predicates and control flow  Aspects inject advice before, after, around…

Looks Nice, However…

Aspect  Base Code Coupling

Fragile Pointcuts Base Code Aspect Code private void initScreens( public aspect ServletContext ctxt, WafViewTemplateHandler extends String language) ExceptionGenericAspect { { … pointcut initScrGetResHdlr(): screenDefURL = withincode( ctxt.getResource(…); private void … TemplateServlet. } initScreens( ServletContext, String)) && call(URL ServletContext .getResource(String)); … }

State—Point Separation Issue Base Code aspect AbortedTranAnalyzer { //========POSSIBLE======== try { pointcut gotOldExc(OldExc ex): … handler(OldExc) && args(ex); } catch (OldExc e) { pointcut abortedTran(Tran tr): t.abortTrans(…); call(* *.abortTrans(..)) throw new && target(tr); GenExc (quot;failedquot;); } pointcut gotGenExc(GenExc ex): initialization(GenExc.new(..)) && target(ex); //======NOT POSSIBLE======= pointcut get3State(OldExc old, Tran tr, GenExc gen): gotOldExc(old) && abortedTran(tr) && gotGenExc(ex); }

State—Point Separation Issue Base Code aspect AbortedTranAnalyzer { //========POSSIBLE======== try { pointcut gotOldExc(OldExc ex): … handler(OldExc) && args(ex); } catch (OldExc e) { pointcut abortedTran(Tran tr): t.abortTrans(…); call(* *.abortTrans(..)) throw new && target(tr); GenExc (quot;failedquot;); } pointcut gotGenExc(GenExc ex): initialization(GenExc.new(..)) && target(ex); //======NOT POSSIBLE======= pointcut get3State(OldExc old, Tran tr, GenExc gen): gotOldExc(old) && abortedTran(tr) && gotGenExc(ex); }

State—Point Separation Issue Base Code aspect AbortedTranAnalyzer { //========POSSIBLE======== try { pointcut gotOldExc(OldExc ex): … handler(OldExc) && args(ex); } catch (OldExc e) { pointcut abortedTran(Tran tr): t.abortTrans(…); call(* *.abortTrans(..)) throw new && target(tr); GenExc (quot;failedquot;); } pointcut gotGenExc(GenExc ex): initialization(GenExc.new(..)) && target(ex); //======NOT POSSIBLE======= pointcut get3State(OldExc old, Tran tr, GenExc gen): gotOldExc(old) && abortedTran(tr) && gotGenExc(ex); }

State—Point Separation Issue Base Code aspect AbortedTranAnalyzer { //========POSSIBLE======== try { pointcut gotOldExc(OldExc ex): … handler(OldExc) && args(ex); } catch (OldExc e) { pointcut abortedTran(Tran tr): t.abortTrans(…); call(* *.abortTrans(..)) throw new && target(tr); GenExc (quot;failedquot;); } pointcut gotGenExc(GenExc ex): initialization(GenExc.new(..)) && target(ex); //======NOT POSSIBLE======= pointcut get3State(OldExc old, Tran tr, GenExc gen): gotOldExc(old) && abortedTran(tr) && gotGenExc(ex); }

State—Point Separation Issue Base Code aspect AbortedTranAnalyzer { //========POSSIBLE======== try { pointcut gotOldExc(OldExc ex): … handler(OldExc) && args(ex); } catch (OldExc e) { pointcut abortedTran(Tran tr): t.abortTrans(…); call(* *.abortTrans(..)) throw new && target(tr); GenExc (quot;failedquot;); } pointcut gotGenExc(GenExc ex): initialization(GenExc.new(..)) && target(ex); //======NOT POSSIBLE======= pointcut get3State(OldExc old, Tran tr, GenExc gen): gotOldExc(old) && abortedTran(tr) && gotGenExc(ex); }

AspectJ-specific Problems  Abstract aspects can’t share pointcuts  Anonymous advice --> hard to advise aspects  Blocks of code inside methods not advisable  Pointcuts can’t parameterize advice

Lack of Advice Parameterization Base Code aspect ExceptionPrinter { pointcut p1(Exc1 ex): try { handler(Exc1) && args(ex); … before(Exception ex): } catch (Exc1 e) { p1(ex) || p2(ex) println(quot;timeoutquot;); { handleExc(quot;timeoutquot;, thisJP); } } try { pointcut p2(Exc2 ex): … handler(Exc2) && args(ex); } catch (Exc2 e) { before(Exception ex): println(quot;net failedquot;); p1(ex) || p2(ex) } { handleExc(“net failedquot;, thisJP); } void handleExc(String m, JoinPoint jp) { println(jp + quot;:quot; + m); … } }

Some Proposed Techniques  Aspect-aware Interfaces [Kiczales, Mezini ‘05]  Open Modules [Aldrich ‘05]  HyperJ [Ossher, Tarr ‘00]  Classpects [Rajan, Sullivan ‘05]  CaesarJ [Aracic, Gasiunas, Mezini, Ostermann ‘06]  XPIs [Sullivan et. al. ‘05]  Explicit Join Points [Hoffman, Eugster ‘07]

Explicit Join Points (EJPs)  Abstract a cross-cutting concern to its most essential form  Invoke the information hiding principle  Model the abstraction explicitly using named join points instead of implicit join points  Reference EJPs in code explicitly  Or use aspects to inject EJP references obliviously

Aspect  Base Code Coupling

Cooperative AOP Methodology AspectJ: 39 AspectBase couplings EJPs: 11 AspectInterface, 15 BaseInterface

Comparison of Approaches  AspectJ: Base Code Aspects  AspectJ with EJPs (Cooperative AOP): Library Interfaces Pluggable Libraries Base Code EJP Interfaces Aspects Scoped EJPs, pointcutargs and thisblock, advice parameterization by type/value, and policy enforcement

Building Aspect Libraries with EJPs  Define semantic interfaces of cross-cutting concerns using interfaces and EJPs  Package these in a JAR  Define aspects that advise the EJPs to implement the cross cutting concerns  Package each implementation in a different JAR  Write base code or aspects to reference EJPs  Choose aspect implementation JAR at load-time  As the EJPs evolve, use aspects to obliviously adapt calls from old EJPs to new EJPs

EJPs Address…  Fragile pointcuts  State—point separation problem  Abstract aspects can’t share pointcuts  Anonymous advice  Blocks of code inside methods not advisable  Pointcuts can’t parameterize advice

Sullivan—Levels of Obliviousness  Language-level (i.e. language support for AOP)  Feature obliviousness—base code unaware of features in aspects, but do know of preconditions  Designer obliviousness—  Base code programmers blissfully unaware…  Pure obliviousness—  Complete, symmetric separation

This Empirical Study What are the tradeoffs between modularity and obliviousness?

This Empirical Study  Refactored Exception Handling for 3 Java Apps:  Using AspectJ  Using EJPs / Cooperative AOP  Empirical Metrics Measuring:  Coupling & Cohesion  Size & Complexity  Separation of Concerns  Reusability  Revisiting ‘Exceptions and Aspects’ @ FSE06 [Filho et. al.] – Thanks!

Target Applications  Telestrada (Java)  220+ classes and interfaces, 3400 LOC  Java Pet Store (Java)  340+ classes and interfaces,17800 LOC  Health Watcher (AspectJ)  36 aspects, 96 classes and interfaces, 6600 LOC  Aspects for CC, distribution, persistence, some EH

Refactoring Strategy (AspectJ) BEFORE AFTER class C { aspect A { void m() throws … { pointcut p(): try { /*body*/ } execution(void C.m()); catch(E e) { … } void around(): p() { } try { } proceed(); } catch (E e) { … } } declare soft: E: p(); } class C { void m(){ /*body*/ } }

Refactoring Strategy (EJPs) BEFORE AFTER class C { aspect A { void m() throws … { scoped joinpoint ejpH() try { /*body*/ } handles E throws …; catch(E e) { … } void around() throws …: } call(ejpScope(ejpH)) } { try{ proceed(); } catch(E e) { … } } } class C { void m() throws … { A.ejpH(){ /*body*/ } } }

Empirical Metrics  Coupling Between Modules (CBM)  Coupling on Intercepted Modules (CIM)  Lack of Cohesion of Operations (LCO)  Lines of Code (LOC) / Concern LOC (CLOC)  Number of Operations (NoO)  Concern Diffusion over Modules (CDoM)  Concern Diffusion over Operations (CDoO)  Concern Diffusion over Lines of Code (CDoLOC)  Reusable Operation Use Percentage (ROUP)

Coupling Metrics  Coupling Between Modules (CBM)  Number of other modules referenced via field access or method call or EJP reference  Extended to include reference to EJP interfaces  [Chidamber, Kemerer 1994] class C { void m1(B var1, B var2) { A.ejpH(){ var1.m3(); } C.m2(); var2.m4(); CBM = 2 } (A and B) static void m2() { … } }

Coupling Between Modules

Coupling Metrics  Coupling on Intercepted Modules (CIM)  # of modules explicitly named in pointcuts  [Ceccato, Tonella 2004] pointcut initScrGetResHdlr(): withincode( private void TemplateServlet. initScreens( ServletContext, CIM = 3 String)) && call(URL ServletContext .getResource(String));

Coupling on Intercepted Modules

Cohesion Metric  Lack of Cohesion in Operations (LCO)  # of method pairs accessing different fields minus # of method pairs accessing common fields  Helps to measure commonality of purpose class C { Object f1, f2, f3; LCO = 2 void m1() { f1=…; } void m2() { f2=…; } void m3() { f3=…; } void m4() { f1=…; f2=…;} } Disjoint Pairs: m1-m2, m1-m3, m2-m3, m3-m4 Non-Disjoint Pairs: m1-m4, m2-m4

Lack of Cohesion of Operations

Size / Complexity Metrics  Lines of Code (LOC)  # of lines of code without whitespace / comments  Concern Lines of Code (CLOC)  # of lines of code required to implement the exception handling concern  Number of Operations (NoO)  Number of declared methods and advice

Lines of Code

Concern Lines of Code

Number of Operations

Separation of Concern Metrics  Concern Diffusion over Modules (CDoM)  # of modules that implement a concern  … OR reference one that does  Concern Diffusion over Operations (CDoO)  # of operations that implement a concern  … OR reference one that does

Concern Diffusion over Modules

Concern Diffusion over Operations

Separation of Concern Metrics  Concern Diffusion over Lines of Code  # of transitions between one concern to another class C { class C { void m() throws … { void m() throws … { try { A.ejpHandler() { /* /* body body */ */ } catch(E e) { … } } } } } }

Concern Diffusion over LOC

% of handlers implemented by abstract aspects or EJP library Exception Handler Reuse

Reusable Exception Handler EJPs  Ignore exception  Print/log exception  Rethrow different exception or its cause  On exception set variable to value  Propagate exception if flagged 16 EJPs covered 74% of all handlers

Empirically, This Happens

Cooperative AOP Can Help AspectJ: 39 AspectBase couplings EJPs: 11 AspectInterface, 15 BaseInterface

Conclusions  Explicit Interfaces and EJP references:  Provided effective means for advice parameterization  Greatly increased aspect reusability  Must be carefully designed, ideally in advance  Greatest software quality achieved when using combination of obliviousness + EJPs

Future Work  JSR-308 includes proposal for annotations on statements  Study interactions between obliviousness and software quality in the presence of multiple cross-cutting concerns kjhoffma@cs.purdue.edu peugster@cs.purdue.edu Download papers, slides, and compiler at http://www.kevinjhoffman.com/

(SUPPORTING SLIDES)

Addressing EJP Explicitness  Use EJPs only when appropriate  Design EJPs so that their presence is minimal Base Code EJP Interfaces Aspects  Use aspects to reference EJPs as appropriate  Aspect-oriented code editors  Fluid AOP [Hon / Kiczales]

Empirical Metrics Formulated…  Coupling, Cohesion, Separation of Concerns  On the reuse and maintenance of Aspect-Oriented software: [Sant’Anna et. al. 2000]  AspectBase Code Coupling  Measuring the effects of software aspectization [Ceccato/Tonella 2004]  http://aopmetrics.tigris.org/

Empirical Studies Emerging…  Separation of Concerns in Multi-agent Systems: An Empirical Study [2004]  Modularizing design patterns with aspects: a quantitative study [AOSD’05]  Composing design patterns: a scalability study of aspect- oriented programming [AOSD’06]  Exceptions and aspects: the devil is in the details [FSE’06]  On the impact of aspectual decompositions on design stability: An empirical study [ECOOP’07]  Towards Reusable Components with Aspects [ICSE’08]  Evolving Software Product Lines with Aspects [ICSE’08]

Explicit Join Point Declarations abstract aspect TranConcern { scoped joinpoint void enterTrans(int isolation) throws TranException; } Keyword to Explicit Name to Associate Declare EJP with Abstract Semantics Optional Constraints Acting Explicit Value Modifiers Upon Base Code Parameterization

Referencing EJPs in Base Code abstract aspect TranConcern { scoped joinpoint void enterTrans(int isolation) throws TranException; joinpoint int defIso() = 1; Some policy aspect could } implement/override this EJP void someMethod() throws TranException { TranConcern.enterTrans(TranConcern.defIso()) { //block of code } Reference to scoped EJP; Reference to } entire block of code is advised EJP in base code

Advising EJPs in Aspects aspect TranConcernViaSomeLibrary { void around(int iso) throws TranException: call(ejpScope(TranConcern.enterTrans)) && args(iso) { TransContext t = …; t.beginTrans(); try { proceed(); /* calls original block of code */ t.commitTrans(); } catch(Throwable e) { t.abortTrans(); throw TranException(e); }}

Advising EJPs in Aspects aspect BillingComponentsTranPolicy { int around(): call(ejp(TranConcern.defIso)) && within (com.me.billing.*) { return 4; } //use a higher isolation level in billing pkg } aspect ForceIsolationLevel { int around(): call(ejp(TranConcern.defIso)) && cflow(call(* CreditCard+.*(..))) { return 5; } //anytime the call stack includes a method } //from the CreditCard class use iso level 5

Add a comment

Related presentations

Related pages

Towards Reusable Components With Aspects [ICSE 2008 ...

1. Towards Reusable Components with Aspects: An Empirical Study on Modularity and Obliviousness Kevin Hoffman ...
Read more

Towards reusable components with aspects: An empirical ...

... Towards reusable components with aspects: ... (ICSE 2008), Leipzig ... to represent cross-cutting concerns as reusable components has yet to be ...
Read more

Towards reusable components with aspects - doi.acm.org

Towards reusable components with aspects: ... 2008, Leipzig, Germany ... ICSEInternational Conference on Software Engineering:
Read more

ICSE 2008: Program - Research Papers

Towards Reusable Components with Aspects: An Empirical Study on Modularity and Obliviousness Kevin Hoffman, Patrick Eugster; ... ICSE 2008 Gold Supporters:
Read more

dblp: ICSE 2008

Bibliographic content of ICSE 2008. ... Towards reusable components with aspects: ... Evolving software product lines with aspects: ...
Read more

Towards Reusable Components with Aspects: An Empirical ...

Towards Reusable Components with Aspects: An Empirical Study on Modularity and Obliviousness Kevin Hoffman Purdue University 305 N. University Street
Read more

ICSE 2008: Program - Day by Day

Official Website of the International Conference on Software Engineering (ICSE) 2008, in Leipzig, Germany. ... Towards Reusable Components with Aspects: ...
Read more

Search results for "Reusable components" – FacetedDBLP

Searching for phrase Reusable components (changed automatically) with no syntactic query expansion in all metadata.
Read more

www.computer.org

Patrick Eugster, Kevin Hoffman, "Towards reusable components with aspects", 2008 ACM/IEEE 30th International Conference on Software Engineering.
Read more