Introduction to AOP, AspectJ, and Explicit Join Points

68
Why you should get excited about AOP and AspectJ (or not) Kevin Hoffman

description

An introduction to and history of aspect-oriented programming. A short overview of AspectJ, certain challenges such as the state-point separation problem, and how explicit join points (EJPs) help mitigate these problems.

Transcript of Introduction to AOP, AspectJ, and Explicit Join Points

Page 1: Introduction to AOP, AspectJ, and Explicit Join Points

Why you should get excited

about AOP and AspectJ

(or not)

Kevin Hoffman

Page 2: Introduction to AOP, AspectJ, and Explicit Join Points

AOP

Page 3: Introduction to AOP, AspectJ, and Explicit Join Points

Cross-cutting Concerns

(Thanks to AspectJDev Tools (AJDT) Visualization Eclipse Perspective)

Page 4: Introduction to AOP, AspectJ, and Explicit Join Points

Cross-cutting Concerns

(Thanks to AspectJDev Tools (AJDT) Visualization Eclipse Perspective)

Page 5: Introduction to AOP, AspectJ, and Explicit Join Points

Aspect-Oriented Programming

Make cross-cutting concerns:

Separated from the ―base code‖

No coupling between base code / cross-cutting concerns

Aim for lexical and semantic separation

Modular Domain experts write the ―hard stuff‖ once

Page 6: Introduction to AOP, AspectJ, and Explicit Join Points

AOP Stratagems

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

Page 7: Introduction to AOP, AspectJ, and Explicit Join Points

History of AOP [1]

Defined by Kiczales et al. @ ECOOP‘97

Functional vs data flow decomposition example

Page 8: Introduction to AOP, AspectJ, and Explicit Join Points

History of AOP [2]

Aspects are properties not ―cleanly

encapsulated‖ (locality / composability)

Page 9: Introduction to AOP, AspectJ, and Explicit Join Points

History of AOP [3]

Aspect Weavers: ―process the component

and aspect languages, composing them

properly to product the … total system …‖

Join Points: ―Those elements of the

component language semantics that the

aspect programs coordinate with‖

Page 10: Introduction to AOP, AspectJ, and Explicit Join Points

History of AOP [4]

Filman/Freiman @ OOPSLA‘00:

`AOP is Quantification and Obliviousness‘

―Distinguishing characteristic‖ … of AOP … is ability to

make ―quantified programmatic assertions over programs

written by programmers oblivious to such assertions‖

‗ ―Just program like you always do, and we’ll be able to

add the aspects later.‖ (And change your mind

downstream about your policies, and we‘ll painlessly

transform your code for that, too.)‘

Page 11: Introduction to AOP, AspectJ, and Explicit Join Points

History of AOP [5]

Sullivan–Levels of Obliviousness (FSE‘05):

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

Page 12: Introduction to AOP, AspectJ, and Explicit Join Points

History of AOP [6]

Languages (countless)

AspectJ – ~2000 / ECOOP‘01

25+ for Java (CaesarJ, Classpects, LogicAJ, EJPs)

13+ for .NET (PostSharp, Aspect#, …)

6+ for C/C++ (AspectC++, XWeaver, …)

37+ for others (Cobol (!), Delphi, JavaScript, Lua,

make, ML, Perl, PHP, Python, Ruby, XML, UML)

Page 13: Introduction to AOP, AspectJ, and Explicit Join Points

AspectJ Introduction

AspectJ (~2000; Kiczales @ ECOOP‘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…

Page 14: Introduction to AOP, AspectJ, and Explicit Join Points

Toy Tracing Example

class Store {

pointcut logEvents():call(* * Store.*(..));

//advicearound(): logEvents() {

println(“”+thisJoinPoint);Object ret = proceed();println(“ret: “+ret);return ret;

}after() throwing(Exception e):

logEvents() {println(“err: ”+e);throw e;

}

JSP Pages aspect Logging {

void buy(…){

try {…

} catch (…) { }}

void cancel(…){

…throw …;

}

void retItem(…){

…}

}}

…s.buy(_order);…

…s.cancel(o);…

…s.retItem(o);…

Page 15: Introduction to AOP, AspectJ, and Explicit Join Points

Toy Tracing Example

class Store {

pointcut logEvents():call(* * Store.*(..));

//advicearound(): logEvents() {

println(“”+thisJoinPoint);Object ret = proceed();println(“ret: “+ret);return ret;

}after() throwing(Exception e):

logEvents() {println(“err: ”+e);throw e;

}

JSP Pages aspect Logging {

…s.buy(_order);…

…s.cancel(o);…

…s.retItem(o);…

void buy(…){

try {…

} catch (…) { }}

void cancel(…){

…throw …;

}

void retItem(…){

…}

}}

println (…)

println (…)

println (…)

Page 16: Introduction to AOP, AspectJ, and Explicit Join Points

Toy Tracing Example

class Store {

pointcut logEvents():call(* * Store.*(..));

//advicearound(): logEvents() {

println(“”+thisJoinPoint);Object ret = proceed();println(“ret: “+ret);return ret;

}after() throwing(Exception e):

logEvents() {println(“err: ”+e);throw e;

}

JSP Pages aspect Logging {

…s.buy(_order);…

…s.cancel(o);…

…s.retItem(o);…

void buy(…){

try {…

} catch (…) { }}

void cancel(…){

…throw …;

}

void retItem(…){

…}

}}

println (…)}catch(…){

println(…);…}

try {

println (…)}catch(…){

println(…);…}

try {

println (…)}catch(…){

println(…);…}

try {

Page 17: Introduction to AOP, AspectJ, and Explicit Join Points

AspectJ Join Points

class Store {

pointcut logEvents():call(* * Store.*(..));

//advicearound(): logEvents() {

println(“”+thisJoinPoint);Object ret = proceed();println(“ret: “+ret);return ret;

}after() throwing(Exception e):

logEvents() {println(“err: ”+e);throw e;

}

JSP Pages aspect Logging {

…s.buy(_order);…

…s.cancel(o);…

…s.retItem(o);…

void buy(…){

try {…

} catch (…) { }}

void cancel(…){

…throw …;

}

void retItem(…){

…}

}}

Page 18: Introduction to AOP, AspectJ, and Explicit Join Points

AspectJ Pointcuts

class Store {

pointcut logEvents():call(* * Store+.*(..));

//advicearound(): logEvents() {

println(“”+thisJoinPoint);Object ret = proceed();println(“ret: “+ret);return ret;

}after() throwing(Exception e):

logEvents() {println(“err: ”+e);throw e;

}

JSP Pages aspect Logging {

…s.buy(_order);…

…s.cancel(o);…

…s.retItem(o);…

void buy(…){

try {…

} catch (…) { }}

void cancel(…){

…throw …;

}

void retItem(…){

…}

}}

Page 19: Introduction to AOP, AspectJ, and Explicit Join Points

AspectJ Advice

class Store {

pointcut logEvents():call(* * Store+.*(..));

//advicearound(): logEvents() {

println(“”+thisJoinPoint);Object ret = proceed();println(“ret: “+ret);return ret;

}after() throwing(Exception e):

logEvents() {println(“err: ”+e);throw e;

}

JSP Pages aspect Logging {

…s.buy(_order);…

…s.cancel(o);…

…s.retItem(o);…

void buy(…){

try {…

} catch (…) { }}

void cancel(…){

…throw …;

}

void retItem(…){

…}

}}

Page 20: Introduction to AOP, AspectJ, and Explicit Join Points

AspectJ Advice

class Store {

pointcut logEvents():call(* * Store+.*(..));

//advicearound(): logEvents() {

println(“”+thisJoinPoint);Object ret = proceed();println(“ret: “+ret);return ret;

}after() throwing(Exception e):

logEvents() {println(“err: ”+e);throw e;

}

JSP Pages aspect Logging {

…s.buy(_order);…

…s.cancel(o);…

…s.retItem(o);…

}}

void buy(…){

try {…

} catch (…) { }}

void cancel(…){

…throw …;

}

void retItem(…){

…}

Page 21: Introduction to AOP, AspectJ, and Explicit Join Points

Pointcuts [1]

Methods and Constructors

call(Signature)

execution(Signature)

Fields

get(Signature)

set(Signature)

Exception Handlers

handler(TypePattern)

Page 22: Introduction to AOP, AspectJ, and Explicit Join Points

Pointcuts [2]

Advice

adviceexecution()

Initialization

staticinitialization(TypePattern)

initialization(Signature)

preinitialization(Signature)

Lexical

within(TypePattern)

withincode(Signature)

Page 23: Introduction to AOP, AspectJ, and Explicit Join Points

Pointcuts [3]

Instanceof checks / context exposure

this(Type or Id)

target(Type or Id)

args(Type or Id)

Control Flow

cflow(Pointcut)

cflowbelow(Pointcut)

Page 24: Introduction to AOP, AspectJ, and Explicit Join Points

Pointcuts [4]

Conditional

if(Expression)

Combination

! Pointcut

Pointcut0 && Pointcut1

Pointcut0 || Pointcut1

( Pointcut )

Page 25: Introduction to AOP, AspectJ, and Explicit Join Points

Pointcut Examples

pointcut setXY(FigureElement fe, int x, int y):

call(void FigureElement.setXY(int, int))

&& target(fe)

&& args(x,y)

after(FigureElement fe, int u, int v) returning:

setXY(fe, u, v)

{

System.out.println(fe+" moved to ("+u+","+v+")");

}

Page 26: Introduction to AOP, AspectJ, and Explicit Join Points

Pointcut Examples

pointcut setXY(FigureElement fe, int x, int y):

call(void FigureElement.setXY(int, int))

&& target(fe)

&& args(x,y)

after(FigureElement fe, int u, int v) returning:

setXY(fe, u, v)

{

System.out.println(fe+" moved to ("+u+","+v+")");

}

Page 27: Introduction to AOP, AspectJ, and Explicit Join Points

AspectJ Pointcuts

class Store {

pointcut logEvents():call(* * Store+.*(..));

//advicearound(): logEvents() {

println(“”+thisJoinPoint);Object ret = proceed();println(“ret: “+ret);return ret;

}after() throwing(Exception e):

logEvents() {println(“err: ”+e);throw e;

}

JSP Pages aspect Logging {

…s.buy(_order);…

…s.cancel(o);…

…s.retItem(o);…

void buy(…){

try {…

} catch (…) { }}

void cancel(…){

…throw …;

}

void retItem(…){

…}

}}

Page 28: Introduction to AOP, AspectJ, and Explicit Join Points

Advice (unit of logic injection)

Specify where to inject aspect logic:

before

after (returning, throwing)

around – use of proceed

Aspect Reflection:

thisJoinPoint encapsulates currently advised join

point, including ability to proceed

Page 29: Introduction to AOP, AspectJ, and Explicit Join Points

AspectJ Advice

class Store {

pointcut logEvents():call(* * Store+.*(..));

//advicearound(): logEvents() {

println(“”+thisJoinPoint);Object ret = proceed();println(“ret: “+ret);return ret;

}after() throwing(Exception e):

logEvents() {println(“err: ”+e);throw e;

}

JSP Pages aspect Logging {

…s.buy(_order);…

…s.cancel(o);…

…s.retItem(o);…

void buy(…){

try {…

} catch (…) { }}

void cancel(…){

…throw …;

}

void retItem(…){

…}

}}

Page 30: Introduction to AOP, AspectJ, and Explicit Join Points

Aspects

Encapsulation of a cross-cutting concern

Collection of pointcuts, state, and advice

Variety of instantiation models:

Singleton, per this/target, per cflow

aspectOf() to retrieve aspect instance in base code

Page 31: Introduction to AOP, AspectJ, and Explicit Join Points

Example Aspect

aspect FieldModificationLogger {

Fieldlog l = new FieldLog(…);

pointcut allSets(Object o, Object newVal):

set(* *.*)

&& this(o)

&& args(newVal);

before(Object o, Object nv): allSets(o,nv) {

l.record(o,nv);

}

}

Page 32: Introduction to AOP, AspectJ, and Explicit Join Points

Modern AspectJ

Intertype declarations

Statically modify types (add/override methods, etc.)

Integration with generics

Only for pointcuts, generics erased for advice

Annotation support

Aspect specification via annotations

Matching based on annotations

Page 33: Introduction to AOP, AspectJ, and Explicit Join Points

AspectJ in Action1

Logging (canonical example)

Pooling / caching

Policy / contract enforcement

Business logic

Security

Transactions

Exception Handling

1) AspectJ in Action: Practical aspect-oriented programming, R. Laddad, Manning, 2003

Page 34: Introduction to AOP, AspectJ, and Explicit Join Points

Empirical Metrics Formulated…

Coupling, Cohesion, Separation of Concerns

On the reuse and maintenance of Aspect-Oriented

software: [Sant‘Anna et. al. 2000]

AspectBase Code Coupling

Measuring the effects of software aspectization

[Ceccato/Tonella 2004]

http://aopmetrics.tigris.org/

Page 35: Introduction to AOP, AspectJ, and Explicit Join Points

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]

Page 36: Introduction to AOP, AspectJ, and Explicit Join Points

Fragile Pointcuts

Base Code Aspect Code

public aspectWafViewTemplateHandlerextendsExceptionGenericAspect

{ pointcut initScrGetResHdlr():

withincode(private voidTemplateServlet. initScreens(

ServletContext, String))

&& call(URL ServletContext.getResource(String));

…}

private void initScreens(

ServletContext ctxt,

String language)

{

screenDefURL =

ctxt.getResource(…);

}

Page 37: Introduction to AOP, AspectJ, and Explicit Join Points

State—Point Separation Issue

Base Code aspect AbortedTranAnalyzer {

}

try {…

} catch (OldExc e) {t.abortTrans(…);throw new

GenExc ("failed");}

//========POSSIBLE========pointcut gotOldExc(OldExc ex):

handler(OldExc) && args(ex);pointcut abortedTran(Tran tr):

call(* *.abortTrans(..))&& target(tr);

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);

Page 38: Introduction to AOP, AspectJ, and Explicit Join Points

State—Point Separation Issue

Base Code aspect AbortedTranAnalyzer {

}

try {…

} catch (OldExc e) {t.abortTrans(…);throw new

GenExc ("failed");}

//========POSSIBLE========pointcut gotOldExc(OldExc ex):

handler(OldExc) && args(ex);pointcut abortedTran(Tran tr):

call(* *.abortTrans(..))&& target(tr);

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);

Page 39: Introduction to AOP, AspectJ, and Explicit Join Points

State—Point Separation Issue

Base Code aspect AbortedTranAnalyzer {

}

try {…

} catch (OldExc e) {t.abortTrans(…);throw new

GenExc ("failed");}

//========POSSIBLE========pointcut gotOldExc(OldExc ex):

handler(OldExc) && args(ex);pointcut abortedTran(Tran tr):

call(* *.abortTrans(..))&& target(tr);

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);

Page 40: Introduction to AOP, AspectJ, and Explicit Join Points

State—Point Separation Issue

Base Code aspect AbortedTranAnalyzer {

}

try {…

} catch (OldExc e) {t.abortTrans(…);throw new

GenExc ("failed");}

//========POSSIBLE========pointcut gotOldExc(OldExc ex):

handler(OldExc) && args(ex);pointcut abortedTran(Tran tr):

call(* *.abortTrans(..))&& target(tr);

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);

Page 41: Introduction to AOP, AspectJ, and Explicit Join Points

State—Point Separation Issue

Base Code aspect AbortedTranAnalyzer {

}

try {…

} catch (OldExc e) {t.abortTrans(…);throw new

GenExc ("failed");}

//========POSSIBLE========pointcut gotOldExc(OldExc ex):

handler(OldExc) && args(ex);pointcut abortedTran(Tran tr):

call(* *.abortTrans(..))&& target(tr);

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);

Page 42: Introduction to AOP, AspectJ, and Explicit Join Points

AspectJ in Action1

Logging (canonical example)

Pooling / caching

Policy / contract enforcement

Business logic

Security

Transactions

Exception Handling

1) AspectJ in Action: Practical aspect-oriented programming, R. Laddad, Manning, 2003

Challenges of AspectJ

Hindered by:

• Tight aspectbase code coupling

• Burden of fragile pointcuts

• State—point separation problem

• Lack of advice parameterization

• Inability to share abstract pointcuts

Page 43: Introduction to AOP, AspectJ, and Explicit Join Points

Solutions?

Explicit Join Points [Hoffman/Eugster]

Bridging Java and AspectJ [PPPJ‘07]

Towards Reusable Components with Aspects: An

Empirical Study on Modularity and Obliviousness

[ICSE‘08]

Cooperative Aspect-Oriented Programming [SCP]

XPIs [Sullivan et.al.] / Classpects [Rajan]

Open Modules [Aldrich]

Page 44: Introduction to AOP, AspectJ, and Explicit Join Points

Motivation for Explicit Join Points

How to stop writing

complex, brittle pointcuts,

just to avoid touching the base code,

and start writing

truly reusable aspect libraries

Page 45: Introduction to AOP, AspectJ, and Explicit Join Points

Is all this

obliviousness

really worth it?

Page 46: Introduction to AOP, AspectJ, and Explicit Join Points

AspectJ Approach

Page 47: Introduction to AOP, AspectJ, and Explicit Join Points

What If Join Points Were Explicit?

Page 48: Introduction to AOP, AspectJ, and Explicit Join Points

Cooperative AOP

Page 49: Introduction to AOP, AspectJ, and Explicit Join Points

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

Enhance EJPs to mitigate the aspect modularity challenges of AspectJ

Page 50: Introduction to AOP, AspectJ, and Explicit Join Points

Explicit Join Point Declarations

Optional

Modifiers

Keyword to

Declare EJP

Constraints Acting

Upon Base Code

Explicit Name to Associate

with Abstract Semantics

Explicit Value

Parameterization

abstract aspect TranConcern {scoped joinpoint void enterTrans(int isolation)

throws TranException;}

Page 51: Introduction to AOP, AspectJ, and Explicit Join Points

Referencing EJPs in Base Code

Some policy aspect could

implement/override this EJP

Reference to

EJP in base code

Reference to scoped EJP;

entire block of code is advised

abstract aspect TranConcern {scoped joinpoint void enterTrans(int isolation)

throws TranException;joinpoint int defIso() = 1;

}

void someMethod() throws TranException {TranConcern.enterTrans(TranConcern.defIso()) {

//block of code}

}

Page 52: Introduction to AOP, AspectJ, and Explicit Join Points

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);

}}

Page 53: Introduction to AOP, AspectJ, and Explicit Join Points

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

Page 54: Introduction to AOP, AspectJ, and Explicit Join Points

EJP Pointcut Arguments

Provide mechanisms for pointcuts to be

defined piecewise in base code:

Allow each piece of such a pointcut to be lexically

close to the fragile join points

Fragile code and pointcuts evolve together

Represent the disjunction of all of the pieces as a

pointcut associated with an EJP declaration

Page 55: Introduction to AOP, AspectJ, and Explicit Join Points

Declaring EJP Pointcut Arguments

interface CompRecord {void compensate();void log(…);

}abstract aspect TranConcern {

scoped joinpoint void enterTrans(int isolation)pointcutargs ignoreableCompensations()throws TranException;

joinpoint void addCompensation(CompRecord r);}

This pointcut models the join points that reference the

addCompensation EJP but should actually be ignored

Page 56: Introduction to AOP, AspectJ, and Explicit Join Points

Defining Pointcutargs Piecewise

void testTrans() throws TranException {TranConcern.enterTrans(TranConcern.defIso())

pointcutargs ignorableCompensations():(call(ejp(*.addCompensation)) &&cflow(call(thisblock)))

{//any references to the addCompensation EJP//in the cflow of this block are included in the full//definition of the pointcut ignorableCompensations

}}

Page 57: Introduction to AOP, AspectJ, and Explicit Join Points

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 obliviouslyadapt calls from old EJPs to new EJPs

Page 58: Introduction to AOP, AspectJ, and Explicit Join Points

Comparison of Approaches

AspectJ:

AspectJ with EJPs (Cooperative AOP):

AspectsBase Code EJP Interfaces

AspectsBase Code

Library Interfaces Pluggable Libraries

Scoped EJPs, pointcutargs and thisblock, advice

parameterization by type/value, and policy enforcement

Page 59: Introduction to AOP, AspectJ, and Explicit Join Points

Addressing EJP Explicitness

Use EJPs only when appropriate

Design EJPs so that their presence is minimal

Use aspects to reference EJPs as appropriate

Aspect-oriented code editors

Fluid AOP [Hon / Kiczales]

AspectsBase Code EJP Interfaces

Page 60: Introduction to AOP, AspectJ, and Explicit Join Points

Related Work

XPIs [Sullivan et al]

Define design rules to shape base code so that

implicit join points have a predictable structure

Write pointcuts against stable design rule patterns

Open Modules [Aldrich]

Restrict advisable join points to be only those that

are explicitly exported by a module

Modular reasoning [Kiczales and Mezini]

Inference of cross-cutting interfaces

Page 61: Introduction to AOP, AspectJ, and Explicit Join Points

EJPs Empirical Case Study [ICSE08]

Page 62: Introduction to AOP, AspectJ, and Explicit Join Points

AspectJ + EJPs Delivers

The separation of cross-cutting concerns:

Syntactically

Semantically (Base code EJPs aspects)

Benefits from obliviousness

Increased modularity of base code ̂ and aspect code

Parallel and domain-specific development

Post-mortem extendibility

Benefits from quantification

Reduction in code size and duplicity

Higher level interaction between primary and cross-cutting concerns (matching against semantic interfaces)

(presence of EJPs)

Page 63: Introduction to AOP, AspectJ, and Explicit Join Points

AspectJ in Action1

Logging (canonical example)

Pooling / caching

Policy / contract enforcement

Business logic

Security

Transactions

Exception Handling

1) AspectJ in Action: Practical aspect-oriented programming, R. Laddad, Manning, 2003

Goal of Reusable Aspect Libraries

Hindered by:

• Tight aspectbase code coupling

• Burden of fragile pointcuts

• State—point separation problem

• Lack of advice parameterization

• Inability to share abstract pointcuts

Page 64: Introduction to AOP, AspectJ, and Explicit Join Points

AspectJ in Action1

Logging (canonical example)

Pooling / caching

Policy / contract enforcement

Business logic

Security

Transactions

Exception Handling

1) AspectJ in Action: Practical aspect-oriented programming, R. Laddad, Manning, 2003

Goal of Reusable Aspect Libraries

Facilitated by:

• AspectEJPbase code decoupling

• Stable pointcuts / pointcutargs

• Scoped EJPs

• Type/value advice parameterization

• Policy enforcement constructs

Page 66: Introduction to AOP, AspectJ, and Explicit Join Points

Example Fragile Pointcuts

public aspect WafViewTemplateHandlerextends

ExceptionGenericAspect{

/*** ScreenDefinitionDAO***/

pointcut loadDocument() :

execution(public static Element

ScreenDefinitionDAO.loadDocument(URL));

/*** TemplateServlet***/

pointcut initScreensGetResourceHandler() :

call(URL ServletContext.getResource(String)) &&

withincode(private void

TemplateServlet.initScreens(ServletContext, String));

pointcut internalGetUserTransactionHandler() :

execution(* TemplateServlet.internalGetUserTransaction());

pointcut internalGetRequestDispatcherHandler() :

execution(private void

TemplateServlet.internalGetRequestDispatcher(..));

/*** com.sun.j2ee.blueprints.waf.view.template.tags.InsertTag ***/

public pointcut aroundExceptionDoNothingHandler() :

execution(private void

com.sun.j2ee.blueprints.waf.view.template.tags.InsertTag.internal

DoStartTag1());

pointcut internalDoStartTag2Handler() :

execution(private void

com.sun.j2ee.blueprints.waf.view.template.tags.InsertTag.internal

DoStartTag2());

pointcut doEndTagHandler() :

execution(public int

com.sun.j2ee.blueprints.waf.view.template.tags.InsertTag.doEndT

ag());

Page 67: Introduction to AOP, AspectJ, and Explicit Join Points

Example Fragile Pointcuts

private void initScreens(ServletContext context, String language) {

URL screenDefinitionURL = null;

screenDefinitionURL = context.getResource("/WEB-INF/screendefinitions_" +

language + ".xml");

if (screenDefinitionURL != null) {

Screens screenDefinitions =

ScreenDefinitionDAO.loadScreenDefinitions(screenDefinitionURL);

if (screenDefinitions != null) {

allScreens.put(language, screenDefinitions);

} else {

System.err.println("Template Servlet Error Loading Screen Definitions: Confirm

that file at URL /WEB-INF/screendefinitions_― + language + ".xml contains the screen

definitions");

}

} else {

System.err.println("Template Servlet Error Loading Screen Definitions: URL /WEB-

INF/screendefinitions_" + language + ".xml not found");

}

}

Page 68: Introduction to AOP, AspectJ, and Explicit Join Points

Example State—Point Separation

/**

* @author [redacted]

*/

public aspect AsyncsenderEjbHandler{

//QueueConnectionqConnect= null;

Map qConnect= new HashMap();

/*** AsyncSenderEJB***/

pointcut sendAMessage() :

execution(public void AsyncSenderEJB.sendAMessage(String));

pointcut createQueueConnectionHandler() :

call(* QueueConnectionFactory.createQueueConnection()) &&

withincode(public void AsyncSenderEJB.sendAMessage(String));

declare soft : JMSException: sendAMessage();

after() returning(QueueConnectionqc) : createQueueConnectionHandler() {

//Save inner method variable to local(multi-thread)

qConnect.put(Thread.currentThread().getName(), qc);

//qConnect= qc;

}

void around() throws EJBException: sendAMessage() {

try {

proceed();

} catch(Exception e) {

e.printStackTrace();

throw new EJBException("askMDBToSendAMessage: Error!",e);

} finally {

try {

QueueConnectionqConnectAux= (QueueConnection)qConnect.get(Thread.currentThread().getName());

if( qConnectAux!= null ) {

qConnectAux.close();

}

} catch(Exception e) {}

}

}

}