HAL Id: hal-02545601
https://hal.archives-ouvertes.fr/hal-02545601
Submitted on 17 Apr 2020
HAL is a multi-disciplinary open access
archive for the deposit and dissemination of
sci-entific research documents, whether they are
pub-lished or not. The documents may come from
teaching and research institutions in France or
abroad, or from public or private research centers.
L’archive ouverte pluridisciplinaire HAL, est
destinée au dépôt et à la diffusion de documents
scientifiques de niveau recherche, publiés ou non,
émanant des établissements d’enseignement et de
recherche français ou étrangers, des laboratoires
publics ou privés.
JAC Milestone 2001
Lionel Seinturier, Renaud Pawlak, Laurence Duchien, Gérard Florin
To cite this version:
Lionel Seinturier, Renaud Pawlak, Laurence Duchien, Gérard Florin. JAC Milestone 2001. [Research
Report] lip6.2001.025, LIP6. 2001. �hal-02545601�
Lionel Seinturier , RenaudPawlak , Laurence Duchien , Gerard Florin
UniversiteParis6,Lab. LIP6,4 place Jussieu, 75252Pariscedex 05, France
CEDRIC-CNAM, 292 rue Saint-Martin, 75141Pariscedex 03, France
USTL-LIFL, B^atiment M3, 59655Villeneuve d'Ascq cedex, France
[email protected],fpawlak, [email protected],Laurence.Duchien@li .fr
Abstract
JAC(JavaAspectComponents)isaframeworkforaspect-orientedprogramminginJava. It isdevelopedasajointresearchprojectbetweentheCEDRIC-CNAMand LIP6computer
science laboratories. ThisreportgivesasnapshotoftheprojectasofSeptember2001. UnlikelanguagessuchasAspectJwhicharemostlyclass-based,JACisobject-basedand
doesnotrequireanylanguageextensionstoJava. ItusestheJavassistclassload-timeMOP. AnaspectprograminJACisa setofaspectobjects thatcanbedynamicallydeployedand undeployedontopofrunningapplicationobjects. Aspectobjects maydenethreekindsof
aspectmethods: wrappingmethods(thatwrapapplicationmethodsandprovidetheabilityto runcodebeforeandafterthewrappedmethods),rolemethods(thataddnewfunctionalities
to applicationobjects), and exception handlers. The aspects composition issue is handled through awell-denedwrapping controllerthat species for eachwrapped object at
wrap-time,runtimeorboth,theexecutionorderofaspectobjects.
1 Introduction
Separation of concernsin software engineering hasalwaysbeena verynatural meansto handle
complexityofsoftwaredevelopments[Par72]. However,modularizingconcernscanbeaverytricky
task for the programmerand rise someissues such as performance, crosscutting,orredesigning
whenthesoftwareisusedinacontextthat isquitedierentfrom theoverseenone. Byhandling
crosscuttingwithinthelanguageorsystem,therecentapproachofAspect-OrientedProgramming
(AOP)[KLM +
97] seemstobeaverypromisingwayforhelping developersto handleseparation
ofconcernsandtoovercomethedrawbacksoftraditionaldesignapproaches.
However,ifAOPintroducesanewprogrammingparadigmthatcomplementsexistingones,itis
clearthatitbringsanewbunchofdiÆcultproblems. Thecompositionofanaspecttoan
applica-tion(theaspectissaidtobewoven)isoneofthem. Severalapproachesexist: AspectJ[KHH +
01]
which is agenerallanguagefor AOP,the composition lter objectmodel [BA01] where aspects
are dened as lters applied upon application objects, aspectual components [LLM99] that
de-ne patterns of interaction with roles and connectors to map these roles to application objects,
subject-oriented programming[HO93][OKH +
95] which decomposes an application into subjects
andprovidescompositionrulestorecomposethem, domainspeciclanguagesto dene
crosscut-tingconcernsbasedonpatternsofevents[DMS01]. Wereviewsomeofthemintherelatedworks
sectionofthispaper.
Nevertheless, when several aspects have to be composed to an application, a given aspect
not only crosscuts the application, but may also crosscutothers aspects. Indeed, aspects may
notbeorthogonalto eachothers. Wecallthis issuetheinter-aspects composition aspect. Some
solutionsexist,e.g. precedencerulesin AspectJ[KHH +
01]or composed connectors inaspectual
to invent somead hoc means to handle it. This problem deeply aects the potential powerof
AOPbymakingaspectslessre-usablethat theyshould beanddramaticallylimitsthesimplicity
ofusingasetofaspects.
Inthispaper,wepresentaframework called JAC(forJavaAspectComponents) [JAC]that
isaproposaltocleanlydealwithinter-aspectscomposition withinanaspect-orientedapplication,
making by this way aspects more reusable. JAC is the continuation of A-TOS [PDF +
00], a
previousworkdevelopedinTcl. Thepaperisstructured asfollows. First,wepointoutthatone
ofthemainprobleminAOPistobeabletoeasilycomposeseveralaspectscomingfromdierent
sources, during thedevelopmentprocess, and while theapplication is running. Insection 3,we
presentJACand thewaywedealwith theinter-aspects composition issueat weave-timeandat
runtime. Section 4presentsa casestudy. Section 5discusses JAC performances. We compare
JACwith other relatedworksin section6. Finally, section 7concludes this paperand presents
somefuture works.
2 Important issues in AOP
Whenprogrammingaspects with anaspect-orientedlanguage,framework,or system(AOS) the
main problems programmers have to face is to handle the consistent composition of aspects.
In a general development process, aspects can be programmed by dierent programmers and
can con ict if nothing is done to avoid it. We call this problem the inter-aspects composition
issue[PDF99]. Thisissuecanoccuratweave-timebutalsoatruntimeandcanbesplitinseveral
sub-problemsof dierent natures. The followinglist shortlydepictssome of themostcurrently
encountered. Most of them remain openissues that are discussed in the AOPcommunity. We
don'tassumeanAOStohandlethemautomatically. WeratherthinkthataneatlydesignedAOS
shouldprovidesolutions(e.g. API,languageconstructs,...) tosupportprogrammersinaddressing
them.
2.1 Weave-time issues
Theweave-timeissuesoccurwhentheweaverweavestheaspects(oraparticularaspect)intothe
base program. Depending ontheAOS, weavingcanbeat compile-timeorat runtime(when an
aspect is dynamically addedorremoved from theapplication). Wename the weave-timeissues
WIn tobeableto referthemlater.
2.1.1 Checking for aspect compatibility with the application(WI1)
Assumingthatweknowthatourapplicationshouldnevercontainagivenaspect,theunderlying
AOSshouldbeabletocheckitstype(assumingtheaspectprogrammerprovidesaformalor
semi-formaltypesystem)andrefusetoweaveit. Forinstance,ifthebaseprogramalreadyimplements
anauthenticationpolicy (by choice or becauseyou addsomeaspect to anexisting application),
thenyoushouldaddacompositionconstraintthatpreventsanauthenticationaspecttobewoven.
2.1.2 Checking for inter-aspect compatibility(WI2)
If weknow that two aspects are incompatible (e.g. some redundancy and fault tolerance
algo-rithms)theprogramcanrefusetoweaveoneaspectiftheotherisalreadywoven.
2.1.3 Checking for inter-aspect dependence(WI3)
Ifanaspectiswovenandneedsanotheraspect(e.g. abindingaspectmayneedanamingaspect),
Ifweknowthattwoaspectsimplementthesameconcernintwodierentways(e.g. twodierent
authentication algorithms or two dierent persistence implementations), then the program can
refusetoweaveoneofbothaspectsorunweavethepreviousoneto replaceitbythenewone.
2.1.5 Orderingthe aspectsat weave-time(WI5)
Regardingajoinpoint(alocationin thebaseprogramwhere aset ofaspects canintercesstheir
behaviors),someaspectsmustalwaysbecalledbeforeothers(e.g. authentication)andsomemust
always becalled after others (e.g. persistence). The AOSshould place the dierent aspects so
thattheyarecorrectlyorderedandso thattheaspectprogrammerdoesnotcareanymoreabout
theothers.
For the ve above described issues, the AOS must be able to dene some checking and/or
orderingrules. Thiscodecan beseenasanaspectthat ruleshowaspectsbehaveregardingeach
others at weave-time. In several works, this aspect has been called a composition aspect. At
weave-time,theweaverwillreferthecompositionaspecttodecidehowto weaveanaspectto an
applicationprogram.
2.2 Runtime issues
Byruntimeissues,wemeantheissuesthatmayoccurwhentheaspectisalreadywoven,andthat
can arise when the execution of a join-point that is intercessed by the aspect occurs. In some
cases,thesetofadvicesthatisdenedintheaspectsforagivenjoin-pointmaychangeregarding
the context. Since itdepends on theexecution context, the weave-timecomposition aspect can
hardlydealwith theruntimeissues. Usingafewexamples,wewill showthattheAOScantake
advantageofusingaruntimecompositionaspecttodealwiththeseissues. Wenametheruntime
issuesRIn tobeabletoreferthemlater.
2.2.1 Checking for intra-aspect consistency(RI1)
Some aspects need to perform context-dependent tests to remain semantically consistent. Let
taketheexampleof acounting aspect, that countsthe numberofcalls to agiven method. The
followingpseudocodeis inspiredfromthe AspectJ [KHH +
01]syntax. Itincrementsthecounter
variablebeforeeach executionof methodA.m1.
aspect CountingAspect {
private int counter;
joinpoint jp1 = ( class A, method m1 );
before jp1 advice1 {
counter++;
}
}
Nowimaginethatmethodm2callsm110times. Theaspectprogrammer(thatisawareofthe
baseprogramcode)canoptimizetheapplicationbyaddinganotherbeforeadviceformethodm2.
aspect WrongOptimizedCountingAspect {
private int counter;
joinpoint jp1 = ( class A, method m1 );
joinpoint jp2 = ( class A, method m2 );
before ( jp1 ) advice1 {
counter++;
counter += 10;
}
}
However,thisaspectiswrongbecause,iftheuserofclassAcallsmethodm2,thenthecounter
willbeincrementedby20(rstby10byadvice2,andnext10timesby1byadvice1)insteadof10.
Thus,theaspectcodeneedsto performacontextualtesttoskiptherstbefore advicewhenthe
secondhasalreadybeenapplied(thisisinformallyexpressedinthefollowingpseudocodebythe
advice2.alreadyApplied()method callthatreturnstrueifadvice2 hasalreadybeenapplied).
aspect OptimizedCountingAspect {
private int counter;
joinpoint jp1 = ( class A, method m1 );
joinpoint jp2 = ( class A, method m2 );
before ( jp1 ) advice1 { if ( advice2.alreadyApplied() ) { skip } counter++; } before ( jp2 ) advice2 { counter += 10; } }
These kindsofaspectshasbeenpointedoutin[BMV00]. Brichauandal. callthem "jumping
aspect" since the join points seems to be jumping around the code depending on the context in
which acomponentisused. Thisaspectcodesupposesthattheaspectsystemisabletomemorize
theaspectadvicesthathavebeenalreadyapplied(notethatAspectJ[KHH +
01]cansupportthis
feature withCFlows). Theskip operationmeansthatthe currentadviceisskipped. Wewillsee
lateronthatthissolutionisnottotallysatisfying.
2.2.2 Skippinganaspect (RI2)
Dependingonthestateoftheapplication(andofthecontext),someaspectsmaybeskippedfor
optimizationmatters. Thiscanbeagenericoptimization,e.g. apersistenceaspectmaybecalled
onlyonetimeoutoftensothattheobjectsstatesaresavedlessoften;oranauthenticationaspect
maybeskippedifweknowthat theclienthasalreadybeenauthenticated. Itcanalsobeamore
application semanticsdependent optimization. Forexample,theGUI aspect couldbeskipped if
weknowthat theactionperformedonthebaseobjectwillnotaect itsgraphicalrepresentation.
Thefollowingpseudocodeskipsapersistenceaspectadvicewhentheloadofthesystemgoes
overagiventhreshold.
after ( jp ) advice1 {
if ( System.getLoad() > THRESHOLD ) { skip }
// serialize and write...
}
2.2.3 Choosinganaspect (RI3)
Wepreviously talkedabout checkingfor aspect redundancy. On theother hand theapplication
programmer coulddeliberately weave several aspectsthat implement the sameconcern so that,
depending on the program context, the AOS could use the aspect that seems to be the most
eÆcient. Forinstance, wecan chooseadierentimagecompressionalgorithm whethertheclient
islocallyor remotelyconnectedorwhethers/heaskedforareal-timeQoS.
Similarlytopreviousexamplesasimplemeanstodealwiththisissueistoapplysome
before ( jp ) advice1 {
if ( Network.getLoad() > THRESHOLD ) {
// low quality compress...
} else {
// high quality compress...
}
}
}
2.2.4 Orderingthe aspectsat runtime(RI4)
Insomecases(that mostofthetimedepend ontheapplicationsemantics)theaspect orderingis
notknownatweave-time. Inthesecases,theAOSshouldbeabletore-ordertheaspectsforagiven
join pointand agiven contextwithin the runtimesystem. Let ustaketheexampleof alogging
aspectthat canswitch fromaverbosemodetoaveryverboseone. Intheverbosemode,thelog
tracesonlythesuccessfullyauthenticatedaccesstoanobject,andintheveryverbosemode, the
logtracesalsothenonauthenticatedaccesstries. Asimplewaytoimplementtheverbosemodeis
toapplytheauthenticationaspectbeforetheloggingaspect,whilsttheveryverbosemodeimplies
thattheauthenticationaspectisappliedafter. Moreover,theapplication programmermaywant
tobeinverbosemodeforasetoftrustedclienthostsandin veryverbosemodeforalltheother
hosts. As aconsequence, the aspect ordering depends on someruntime contextual information
andtheAOSshouldprovidefeaturesto helptheprogrammerto dealwiththisin acleanway.
Thisissuecanbeovercomebyusingtwodierentadviceswithcontextualtestssothatitdoes
notseemtobeaproblemanymore(here,weassumethattheweave-timecompositionaspectorder
theadvicessothat advice1 isbefore theauthenticationadvices,andadvice2 isafter).
aspect LoggingAspect {
private boolean veryVerbose;
joinpoint jp = ( class A, getAllMethods );
before ( jp ) advice1 { if ( ! veryVerbose ) { skip } write ( logFile ); } after ( jp ) advice2 { if ( advice1.allreadyApplied() ) { skip } write ( logFile ); } }
2.2.5 Inter-aspectdependence atruntime(RI5)
Assumingthatwecanskipanaspectatruntime,theWI3issueisalsoapplicableatruntime. For
instance,ifweskipatracingaspect,alltheaspectsthat depend onitmustalsobeskipped.
2.3 Discussion
As one can see in gure 1, the aspect composition issue is a critical point in Aspect-Oriented
Programming. In most of the existing languages or systemsthat more or less support
aspect-orientation,handlingtheseissuesismostlypartoftheaspectprogrammertask(likeshowninthe
previousexamples). Thisisaveryimportantlimitationto AOPsincethecomposition issueisa
crosscutting concernin thesense that somecodeshould beadded inthe wholeset of aspectsto
dealwith it, especially when thecomposition problem cannotbeentirelysolvedat weave-time
Aspects with composition and optimization
Hardly maintanable. Application dependent.
rules croscutting. Hardly re-usable.
no composition or
optimization rules
plugged into.
Weaver
simple weaver with
Weaver
rules croscutting. Easily re-usable.
optimization rules
plugged into.
composition and
Hard to maintain.
Hard to reuse.
Possible aspect-oriented systems designs
without a Composition Aspect
Simple aspects with no composition and optimization
Complex weaver with
Even worse, you can get a mix of them
Application dependent.
with a Composition Aspect
no composition or
optimization rules
plugged into.
Weaver
rules croscutting. Easily re-usable.
Composition Aspect
composition
rules
dependent but
easy to maintain
Easy to understand
Externalized
Simple weaver with
Simple aspects with no composition and optimization
A JAC-like aspect-oriented system design
May be application
Figure1: With orwithoutaCompositionAspect?
Toillustrate this,letustakeagainthecountingaspectdepictedin section2.2.1. Theapplied
optimization (incrementing the counter by 10 when m2 is called) skips the default increment.
However, for other base programs, such optimization can be applied for several other kinds of
join-points. Thus theskippingtest isdiÆcultto generalizeand theaspect canhardlybereused
as this. Moreover, another aspect could use the same kind of contextual test (for instance, a
securityaspectthatalso needsto countthecallstom1). Thesameproblemoccurs fortheother
exampleswhentheaspectscheckthesystemornetworkloadstoknowiftheyhavetobeapplied.
Regarding this, it becomes clear that the contextual tests crosscut the aspects and makethem
hardly maintainableand reusable. Inaddition, sincethesamecontextualtests mayappearin a
setofaspectsforthesamejoin-point,theycannallyleadtoperformanceissues.
Forus, theonly way to solvethe runtime issuesis to externalize thecontextual tests into a
well-modularizedinter-aspectcompositionaspect. If wecandothis,the AOS canapply aglobal
contextual test for each join point and handles all the contextual tests at once. As shown in
gure1,theaspectsremainfreefromruntimeissuespollutionandaremoreeÆcientandeasierto
maintainin comparison withother approacheswithoutcontextualpartand aspect composition.
Regardingourexamples,itappearsthatwecanclassifytheruntimeissuesintotwocategories: the
issuesthatinvolveonlyoneaspect(RI1,RI2,andRI3),andtheonesthat involveseveralaspects
(RI4,RI5).
Inthenextsection,wepresentourframeworkcalledJAC(forJavaAspectComponents). With
JAC,programmers developapplications in an aspect-oriented fashion and have support for the
applicationwithin awell-bounded partoftheprogramcalledawrappingcontroller.
3 The JAC framework
Thissectionpresentsourframework. Section 3.1givesanoverview. Thefour softwareentitiesof
anJACaspect-orientedprogramareintroduced. Each ofthemis describedwith moredetails in
theremainingsubsections. Section3.6presentssomeadditionalelementsfromtheJACAPI.
3.1 Overview
JAC is a Java framework that provides support for dynamic aspect-oriented applications. By
dynamic, wemean that an aspect can be woven and unwoven at runtime. An aspect-oriented
programinJACisentirelywritteninregularJavaandiscomposedoffourmain parts.
3.1.1 Baseprogram
AJACbaseprogramiscomposedofasetofJavaobjectsthatimplementthecorefunctionalities
oftheapplication. TheseobjectsrunonaregularJVM.
3.1.2 Aspect programs
Aconcernthatrenesormodiesthebaseprogrambehaviorisimplementedinanaspectprogram
that can be woven to the base program. An aspect program is implemented by aset of aspect
objects (also called dynamic wrappers) that can hold three kinds of aspect methods wrapping
methods, role methods, and/or exception handlers. Contrary to AspectJ [KHH +
01] that mixes
join-pointsdenitions and advice denitions within the sameaspect code, weseparate the core
functionalities of the aspects within independent aspect objects that can be compared to pure
advice sets. Thejoin pointsare dened bythe weaverand thelink betweena join-pointand a
pureadviceisdoneatweave-time. Thischoicemakestheadvicesmorereusableand,forinstance,
several aspects can reuse the sameadvice (for instance, a counting advice can be reused for a
security orforadebugging aspect). This design choice is similarto the onemade byaspectual
components [LLM99]. Compared to this approach, a JAC aspect program corresponds to an
aspectualcomponent,andaJACaspect objectcorrespondstoaparticipant.
Wrapping methods: A wrapping method can wrapanymethod of anybase objectand
seamlessly executes some code before and after this method (they are thus equivalent to
the before, after, and around advices of AspectJand to the replace keywordof aspectual
components). Abasemethodcanbewrappedbyasmuchwrappingmethodsasneededand
a wrappingmethod canbeadded and removedat runtime(contrary to regular wrappers,
JACwrappersdonotchangethebaseobjectreferencewhenwrappingitandimplementthe
wrappingbyusinganinternalanddedicatedMOP).
Role methods: A role method canbe attached to one or many base objectsat runtime
andextendthebaseobjectinterface(similarlytotheintroducestatementinAspectJandto
theparticipantmethodsofaspectualcomponents). Arolemethodcanbeinvokedbycalling
theinvokeRoleMethod onabaseobject.
Exceptionhandlers: Anexceptionhandlerisamethodthatisnotiedwhenanexception
israisedwithin(orfrom)thebaseobjectmethoditisattachedto. Forinstance,thisisvery
usefulwhen theinvokedobjectis wrappedbyawrappingmethod thatraises anexception
Theweaverisresponsiblefordeployingtheaspectobjectsontheappropriatebaseobjectssothat
asetoffunctionalitiescrosscutthebaseprogramandimplementanewconcern. Theweavingcode
implicitlydenespointcutsandlinkstheadvices(wrappingmethods,rolemethodsandexception
handlers) to them. Since thecomposition rulesare externalized within the composition aspect,
theweaverdoesnottakethisissueintoaccount. Theweavingprocessisconguredbyaproperty
le that says where and when aspect objectsare to bedeployed. This le is described in more
detailsin section3.4.
3.1.4 Compositionaspect
Thispartdenesrulesabouthowthedierentaspectsoftheprogramarecomposedatweave-time
(tosolveWI1,...,WI5)oratruntime(tosolveRI1,RI2,RI3). Thecompositionaspectprovidesan
WrappingController interfacethatisaMOPdedicatedtoaspectcompositionandthatisimplicitly
upcalled bythesystemeach timesomecomposition issuecanoccur. Forperformanceissue, the
composition MOPis notactivated by default(since it is sometimes notneeded). The weaveris
responsibleforactivatingthecompositionMOPforagivenbase object.
Figure2sumsupthearchitectureofJACprograms. Table1comparestheJACprogramming
modelwiththeAspectJ[KHH +
01]andtheaspectualcomponents[ML98]ones. Contrarytothese
twoexamples,theJACmodelexternalizestheRuntimecompositionrulessothattheaspectsare
morereusable. OnlyAspectJ integratesitspointcut denition within theaspect entities. Thus,
reusingaspectsimpliesthedenition ofabstractaspectclasses.
3.2 Base objects
Baseobjectsareregular Javaobjectswhose classesare automatically adapted tobeable to
dy-namicallyaddawrapper,attacharoleobject,oranexceptionhandler. Thistranslationisdoneat
classload-timewiththeJavassist[Chi00]tool. SinceJavassistworksonthebytecodeandduring
load-time,thesourcecodeisnotneededand theclasslesof theprogramareneverchangedon
disk. Programmerscanstillusethemtobuild regularJavaapplications.
Figure3zoomsonaJACobjectthathasbeentranslatedbytheJACclassloaderandthat
ini-tiallyoerstwomethodsm1 andm2. TheJavassistmeta-classeswedeveloppedaddthefollowing
elements:
awrappingchain(avectorofreferencestowrappingmethods)foreachinitialmethod,
aset of referencesto exceptionhandling methods(methods called ifthe kindof exception
theycatchisraised) foreachinitialmethod,
aeld that containsareferenceto thewrappingcontroller(upcalled tohandle the
compo-sition,asitwillbeexplainedlater),
avectorthatcontainsreferencestowardstheroleobjectsattachedtotheJACobject.
These dataare manipulated by theweaverthat usestheJACObjectManipulationInterface
that is also added at load-time and that furnishes methods to manipulate wrappers (wrap,
un-wrap, nextWrapper), role objects(addRoleObject, rmvRoleObject, invokeRoleMethod), exception
handlers(addExceptionHandler, rmvExceptionHandler).
Intheexampleofgure3,thecongurationappliedbytheweaver(atruntime)isthefollowing:
m1 iswrappedbyfao1,wm1g andfao1,wm2g,itisattachedtooneexceptionhandlingmethod
base object is
wrapped and
implement a
given composition
policy
notify when a
has to start
tell when the weaving
has to be translated
to become Jac objects
tell what classes
Aspect 1
Aspect N
notify when a new
instance is created
jac.prop file
The base program (regular Java
objects translated at load-time
by Javassist)
add role objects
add exception handlers
wrap
The weaver (deploys the
aspect objects so that the
aspect program crosscuts
the base program)
The composition aspect
(wrapping controllers that
can perform contextual
operation on the wrapping
chains at runtime)
The optimization aspect
(specialize the composition
aspect to perform wrappers
aggregation when possible)
Aspect objects with: wrapping methods, role methods, exception handlers
use for weaving
Figure2: JACapplicationsarchitecture.
Features JAC AspectJ AspectualComponents
Aspect
de-nitions
aspectprograms aspectclasses aspectualcomponents
Aspect
enti-ties
aspectobjects aspectclasses participants
Aspect
enti-tiesmembers
OO model members,
wrapping methods,
role methods,
excep-tionhandlers
OO model members,
pointcuts,advices
(be-fore/after/around/
introduce)
OO model members,
re-place
Pointcut
def-initions
loca-tions
weavers aspectclasses connectors
Weave-time
composition
wrapping controllers
(before/afterWrap)
precedencerules compositeconnectors
Runtime composition wrapping controllers (getNextWrapper) aspect classes (CFlows)
ao1
ao2
beforeWrap
afterWrap
beforeUnwrap
afterUnwrap
getNextWrapper
beforeNewRoleObject
afterNewRoleObject
beforeNewExceptionHandler
afterNewExceptionHandler
private method
java object
java class
public method
added at class load-time
public method or role method
exception handling method
wrapping method
field
reference
wm2
wm1
get/setObject
pushFrame
popFrame
peekFrame
JacObject (informations on
the running system)
other Jac objects
m1
_org_m1
m1 wrapping
chain
m1 exception
handlers
m2 exception
handlers
chain
m2 wrapping
_org_m2
role objects
wc (WrappingController)
wrapping controller
h1
h2
r2
r1
wm3
aspect object 1
aspect object 2
(JacObject)
a base program object
m2
wrap
unwrap
addRoleObject
nextWrapper
rmvRoleObject
rmvExceptionHandler
addExceptionHandler
invokeRoleMethod
setWrappingController
Figure 3: AJACobjectoverview.
3.3 Aspect objects
Asdescribedin section3.1.2,aspectobjectsinJACarecontainersforwrappingmethods and/or
role methods and/or exception handlers. There is no dedicated declaration nor conguration
neededtodistinguishbetweenthesethreetypes. Theyaredynamicallyinferedandcheckedfrom
themethodsignature. Whentryingtouseamethod asawrappingmethod,either thesignature
comply to theoneof awrapping method andthe binding isaccepted, either itdoesnotand in
thiscase,anexceptionisraised. Theprocessisthesameforrolemethodsandexceptionhandlers.
Thissectionpresentsthethreelegalsignaturesforaspectmethods.
3.3.1 Wrapping methods
Wrappers in JAC are not like regular wrappers. Instead of sharing the same interface as the
wrappees,allJACwrappershasthesameMOP-likeinterfacewithareferencetothebaseandan
arrayofparameters. Nevertheless,theyarenotmeta-objectsin thesense that:
method,
awrappingmethodcanwraponeorseveralbasemethods (denedin thesameordierent
classes).
Awrapping method is required to be public andto returnan Objectinstance. This object
willbeinmostcasestheonereturnedbythebasemethod. Nevertheless,itsvaluecanbechanged
ifanyposttreatmentsarepartofthewrappersemantics. Itsclasscanalsobechangedevenifthis
situation should beless common. Indeed,from a client pointof view, thewrapping mechanism
must remain transparent. Thus, if on the server object side, a wrapper modies the return
parameterclass, then on theclientobject side, another wrapperwill be requiredto restore the
expectedclass.
public Object wrappingMethodExample
( Wrappee wrappee, String methodName, Object[] methodArgs, int rank );
The rst argument of a wrapping method is a Wrappee reference. This is the reference of
the base objectcurrentlywrapped by these wrappers. Note that this valuemay change during
thelife ofawrappee aswrapperscanbedynamicallyattached andremovedfrom abase object.
The Wrappee interface corresponds to the JAC Object Manipulation Interface mentionned in
section 3.2. The second argument of a wrapping method is the wrapped method name. The
third one is thearray of argumentsthat are to be transmitted to thebase method. As for the
returnargument,these valuescanbechangedprovidedthat the basemethod canretrievesome
semantically correct valuesfrom them. Thelast argument givesthe rankof thewrapper in the
wrappingchain.
Apart for logging purpose, the value of the rank argument is mainly used when calling the
nextWrappermethod oftheWrappeeinterface. Thismethod eithercalls thenextwrapperin the
chain,orthebasemethodifthecurrentwrapperisthelastoneinthechain. Notethatthisdefault
behaviorprovided by thewrapping controller that can beredened. Note also that the callto
nextWrapper is optional: if omitted, the execution returns to the caller without going neither
throughtherest ofthechain,northebasemethod. Inmostcases,thecalltonextWrapperlooks
likethefollowing:
Object ret = wrappee.nextWrapper( methodName, methodArgs, rank );
The four above described arguments are automatically set by JAC whenever a wrapping
method is called. A wrappingmethod signature can alsocontain anylist of exceptionsrequired
bythewrappersemantics.
3.3.2 Rolemethods
The only thing that is requiredfor amethod to qualify as a role method is to be public. The
returntypemaybeanobject,abasictype(suchas int),orvoid. Programmerscandeneany
numberofargumentsin itssignature. Iftherstone classisWrapppee,it willbeinterpretedby
JACas areferenceto the wrappee objectto whomthis role method is attached. Role methods
canalsoraiseexceptions.
public Object roleMethodExample( Wrappee baseObject, ... );
Role methods are invoked with the invokeRoleMethod method provided by the Wrappee
in-terface. Thesignature of theinvokeRoleMethod method is the sameasthe
java.lang.re ect.Me-thod.invoke method(ieastringforthenameoftherolemethodtoinvokeandsomeargumentsas
anarrayofobjects). Atypicalcallwilllooklike:
Exception handling methods must be public and return void(they can return something else
but this is useless as this value will be discarded in all cases). They require as an argument
an object that represent the exception raised. The class of this object is usually a subclass of
java.lang.Exception althoughJACdoesnotrequireit(ieanyclasswillt).
public void catchExample( ExException e );
The followingsample sumsupthesignaturesof thethreepossibleaspect methodtypes with
JAC.
public class AspectObjectExample {
/**
* Wrapping method example.
* All arguments are set by JAC.
*/
public Object wrappingMethodExample
( Wrappee wrappee, String methodName, Object[] methodArgs, int rank )
throws ExException {
/** before code ... */
if ( [...] ) { throw new ExException(); }
/**
* Call to the next wrapper or
* to the base object if there is no more wrappers.
*/
Object ret = wrappee.nextWrapper(methodName, methodArgs, rank);
/** after code ... */
}
/**
* Role method example.
* The first (optional) parameter is automatically set by JAC
* as a reference on the base object.
* The method can contain any list of user specified parameters.
*/
public Object roleMethodExample( Wrappee baseObject, ... ) {
/* ... */
}
/**
* Exception handler example.
* ExException is the class of the exception caught by this method.
* Usually this is a subclass of java.lang.Exception
* although JAC does not require it (ie any class will fit).
*/
public void catchExample( ExException e ) {
/* ... */
}
Weaversare responsible fordeploying aspect objectsand wrappingcontrolleron topof running
baseobjects. Aweavermustextendthejac.core.Weaverclassandredenethe
public void weave();
method. Section4.2givesarunningexampleofsuchaweaver. Thewaytheweavemethodis
upcalled duringthe baseprogram executionisdened in apropertyle (jac.prop)that resides
inthecurrentworkingdirectory. Twopropertiesarerequired:
jac.weaver: gives the weaverclass (ie the subclass of jac.core.Weaver that provides the
customized weavemethod,
jac.startWeavingPlace: deneswhereandwhentheweavermustbecalled. Thevalueof
thispropertyisaspace-separatedlistoffour arguments.
Fromagenericpointofview,aweavercanbecalledwheneveramethodiscalledonaJACbase
object 1
. Therst twoargumentsdene which class andwhichmethod within this classisto be
monitored. Theanykeywordisashortcutto monitorallthemethodsoftheclass. Polymorphic
methods are not distinguished. The remaining two arguments of the jac.startWeavingPlace
propertyarenumbers: therstoneisaninstancecount,andthesecondoneamethodcallcount.
Both are 0-starting counters and allowto specify policies such as "upcall the weaver on the ith
call to method m on the jth instance of class c". Instances areconsidered in the order in which
they are createdin the base program. The followingsample upcalls theweave method of class
AgendaWeaverontherstcallofanymethodontherstinstanceoftheAgendaClientclass:
jac.weaver: AgendaWeaver
jac.startWeavingPlace: AgendaClient any 0 0
Othermorecomplexpoliciesmayalsobespecied. Forinstance:
jac.startWeavingPlace: AgendaClient printAll 1 5
upcalls theweave method of class AgendaWeaveron the 2nd callof anymethod on the 6th
instance of the AgendaClient class. As aweavermust deploy aspect objects on top of running
applicationobjects,oneofitskeycharacteristicsistobeabletoaccessthem. Unfortunatelythere
is no standardway of doing this with the re ection API of Java (eg there is no such thing as
accessingalltheinstancesofagivenclass). Tosolvethisissue,JACprovidesaAPIthatdoesjust
that. Basically, ashadow referenceto each newJACobjectinstance isautomatically registered
inahashtable. Then,method
public static Object[] getObjects( Class c );
in classJacObjectreturnsanarrayofreferencestoinstancesofclassc.
3.5 Wrapping controllers
Wrapping controllers are JAC software entities that deal with the composition aspect both at
weave-time and at runtime. A default wrapping controller is provided but can be customized
bysubclassingjac.core.WrappingController. Anybaseobjectcanbeattachedto adedicated
wrappingcontroller,orthesamecontrollercanbesharedamongseveralbaseobjects. Section4.3
givesarunningexampleofawrappingcontroller.
Theimportantpointtonoticeisthatwrappingcontrollerexternalizethecompositionissueof
aspect-orientedprograms. Thusaspectandbaseprogramscanstayfreeofdependanciesresolving
codebetweenaspects (thatoccurat weave-time) andofcontextualtestsontheeectiverunning
ofanaspect(thatoccurat runtime).
1
Althoughthiscouldseemto bealimitation(egaweavercannot becalledwhenaobjectreadsa variable), thisisaratherfaircompromiseasmostoftheimportantstuinanobject-orientedprogramissupposedtohappen throughmethodcalls. Morecomplextriggeringscheme(eggroupsofmethodscalls,codepatterns,...) couldalso beenvisionedbutareoutofthescopeofthisdocument.
Weave-time issues mentionned in section 2.1 are adressed by reifying the wrapping mechanism.
ThuseachtimethewrapmethodisinvokedonaJACobjectthecallisinterceptedbythefollowing
methodofthewrappingcontroller:
public int beforeWrap( Wrappee wrappee, String wrappee_method_name,
Wrapper wrapper, String wrapper_method_name,
int default_rank );
Solutions to weave-timeissuescan beimplementedby sayingthat either awrappermust be
rejected(ienotwrapped),orinsertedatagivenposition inthewrappingchain. ThebeforeWrap
method iscalled withthereferenceof theobjectto be wrapped(socalled wrappee),themethod
nametobewrapped,thewrapperandthewrappingmethodname. Thelastargumentdefault rank
istheposition atwhich thewrapperwillbeinsertedin thechainif nothingisdoneto change it
(bydefaultattheendofthechain). Thismethodreturnsanintegerwhichistheeectiveposition
(the same or a new one) choosen for this wrapper. By default, the beforeWrap method does
nothing(morepreciselyitsimplyreturnsdefaultrank). Thismechanismallowsustoimplement
precedencerules (WI5). Since rank-1means that thewrappermust notbe added, wecanalso
implementexclusionrules(WI1toWI4).
A afterWrapmethod withthesamesignaturethan beforeWrapis alsoavailable inthe
Wrap-pingControllerinterface. Thismethodisupcalledaftertheeectiveinsertionofthewrapperinthe
chainandgivestheabilitytoimplementanypost-treatmentrequired. beforeUnwrap,afterUnwrap,
beforeNewExceptionHandler, afterNewExceptionHandler, beforeNewRoleObject,
afterNewRoleOb-ject methods are also available. They perform the same job for respectively the unwrapping
mechanism,theaddingofanexceptionhandler, andtheaddingofarolemethod.
3.5.2 Runtimeissues
Section2.2showsthattheexecutionofawrapperissubjecttosomecontextualtests. Toproduce
better maintainable code, we think that a good design principle is to externalize these tests so
thattheydonotcrosscutandpollutetheaspectcodes.
This externalization is adressed by reifying the dispatch mechanism between each wrapper
of the chain and betweenthe wrappersand the base object. Thus each time the nextWrapper
methodisinvokedonaJACobjectthecallisinterceptedbythefollowingmethodofthewrapping
controller:
public int getNextWrapper( Wrappee wrappee, String wrappee_method_name,
Object[] wrappers, Object[] methods,
int default_rank );
Solutions to runtime issues can be implemented by saying that either a wrapper must be
executedatitscurrentrankinthechain,skippedorexecutedlater. ThegetNextWrappermethod
iscalledwiththereferenceofthewrappedobject,thewrappedmethodname,thearrayofwrappers
ofthechain,andthe arrayofwrappingmethods ofthechain. Thelast argumentdefault rankis
the position of the wrapper in the chain. This method returns aninteger which is the rankof
thenextwrapperto eectivelyrun. Bydefault, thegetNextWrappermethod doesnothing(more
preciselyitsimplyreturnsdefault rank).
The sequence diagram shown in gure 4 sums up the dispatch process and focuses on the
objectsinteractions within the JAC system when amethod is called. This protocol allows the
wrappingcontrollertoentirelycontrolthewaywrappersareappliedatruntime. Thegureshows
the(simplied)caseofamethodm that iscalledonabaseobjectoandthatis wrappedbytwo
wrappingmethods(wm1 andwm2). Onecanseethatthewrappingcontrolleriscalledwhenthe
wrapping method has nished its before work and calls thenext wrapper. Thus, the wrapping
(WrappingControler)
o
w1
w2
wc
getNextWrapper(...)
wm1(...)
nextWrapper(...)
wm2()
nextWrapper(...)
getNextWrapper(...)
(Wrapping methods)
(Wrappee)
m(...)
_org_m(...)
Figure4: Thewrappingcontrolmechanism.
3.6 Additional JAC API
JACintroducestwoadditionalsetsofAPItohandletheexecutionstackandtheexecutioncontext
ofaJavaprogram. Thesefeaturesarenotdirectlyrelatedtoaspect-orientedprogramming.Rather
theyaregeneralfeaturesthatformanyreasons(amongotherperformance)shouldbeincludedin
thecoreAPIoftheJDK.AstheyarenotandasJACaspectprogramsusethemextensively,we
felttheneedtoprovidethem.
3.6.1 Programstack
The ideahere is to be able to querythe execution stack of aJava thread. Each frame on this
stackcontainsthreeelements: thecalledobject,thecalledmethod,andtheexecutioncontext(see
section 3.6.2). These data are automatically pushedby JAC.Obviously, therst frame pushed
ontothestackcorrespondstotherstmethodcalledontherstJACobjectoftheprogram. The
stackcanbequeriedwiththefollowingstaticmethod ofthejac.core.JacObjectclass:
public static Object[] peekFrame( int index );
The index is an integervalue between 0 and 2corresponding to the three above mentioned
elementspushedontothestack. Thismethodreturnstheelementspushedasanarrayofobjects.
Hence,JacObject.peekFrame(1)returnsthechainofcalledmethodnamesasanarrayofobjects
(elementsthenneedtobecastedtostringsbyprogrammers).
Note that somekindof stackmanagement is provided in the API ofJDK 1.4. Nevertheless
its use is a bit cumbersome as it requires to raise and catch an exception before calling the
Executioncontextsin JACarehashtablesthat map attributenames tovalues. Theyarethread
dependantandallowustopropagatedataalongacallgraph. TheJACAPIprovidesmethodsto
getthecurrentcontext(methodgetContext),andtoadd(methodaddAttribute)andget(method
getAttribute)attributes. Eachattributeisapaircomposedofakeystringandofvalue(thatcan
beanyJavaobject).
/** The following method is defined in the jac.core.Jacobject class */
public static jac.core.Context getContext();
/** The following methods are defined in the jac.core.Context class */
public void addAttribute( String name, Object att );
public Object getAttribute( String name );
public void setAttribute( String name, Object att );
4 Case study
This section presents theway anaspect-orientedapplication is developpedwith JAC. Ina rst
stepforclaritysake,wewillnotexternalizethe compositioncode. Itwill bedonein section4.3.
We take the simple example of a agenda application. In this application, the agenda class is
denedasfollows:
public class Agenda {
/** The agenda ID (must be unique) */
public String id;
/** The appointment list */
public Vector appointments = new Vector();
/** The repository for the agendas */
public static AgendaRepository repository;
/** Creates a new agenda and registers it into the repository */
public Agenda( String id, AgendaRepository repository ) {...}
/** Make an appointment with other users */
public void makeAppointment(
String agenda_id, String date, String object, String[] with ) {
// resolve the agendas of the with array with the repository
// call the makeAppointment method on all these agendas
}
/** Print the appointments */
public void printAppointments() {
System.out.println( "** Appointment list for " + id + ":" );
for (int i = 0; i < appointments.size(); i++) {
printAppointment( i );
}
}
/** Print an appointment */
}
}
Itiseasytogureoutthattheagendarepositoryclassimplementssomemethodstoregisterand
toresolveagendawithastringID.WealsoassumethatanAgendaClientclassthatcallsAgenda
instancesisdened.Thus,aclientprogramofanagendacan,forexample,useamakeAppointment
methodthat takesanIDandthatcanbeimplementedas follows:
public class AgendaClient {
/** The repository for the agendas */
public static AgendaRepository repository;
/** Make an appointment with other users */
public void makeAppointment(
String agenda_id, String date, String object, String[] with ) {
Agenda a = repository.resolve( agenda_id );
a.makeAppointment( date, object, with );
}
// Same principles can be applied
// to the printAppointments methods ...
}
4.1 Aspects
4.1.1 Countingaspect
ThisaspectillustratestheRI1issueofsection 2.2.1. Theideais tobeableto countthenumber
oftimes theprintAppointments bytheprintingmethodsof themethod iscalled. As depictedin
section 2.2.1, asimple but not optimized way is to create a wrapper that simply increments a
counter.
public class CountingWrapper {
int counter;
public Object incr( Wrappee wrappee, String meth, Object[] args ) {
counter++;
return wrappee.nextWrapper( meth, args );
}
}
Inthis example,incris thewrappingmethod. Notice, that,at this stage,youdonotspecify
that theincr method will wraptheprintAppointment method. This will bedened later in the
weaver. Forthisreason, our aspectobjectscan be regardedaspure advicesthat canbereused
forseveralaspects.
Asdepictedinsection2.2.1,thiswrappercanbeoptimizedtoavoidseveralcalls(oneforeach
agenda)totheincrwrappingmethodwhentheprintAppointments methodiscalled. Thefollowing
aspectdenestwowrappingmethods: incrforprintAppointment likemethods,andmultiIncrfor
printAppointments likemethods. incrtakesadvantageof theJACAPI (call to JAC.peekFrame
method) and checks whether the client calling method is printAppointments. If so, nothing is
doneasthe update ofcounteris handled elsewhere. If not,printAppointment hasbeendirectly
called and counter needsto beincremented. multiIncr increasesthe valueof counter depending
ofthenumberofagendasin theapplication object(weusetheJavare ectionAPIto introspect
int counter;
// The following fields allow the wrapper to be generic and
// customizable regarding the base program class it has to count.
String field, callingMethod;
public CountingWrapper( String field, String callingMethod ) {
this.field = field; this.callingMethod = callingMethod; } public CountingWrapper() { field = "appointments"; callingMethod = "printAppointments"; }
public Object incr( Wrappee wrappee, String meth, Object[] args, int rk ) {
// we increment the counter only
// if the calling method is "printAppointments".
if ( ! ( JacObject.peekFrame(1)[0] == wrappee &&
JacObject.peekFrame(1)[1] == method ) )
counter++;
return wrappee.nextWrapper( meth, args, rk );
}
public Object multiIncr( Wrappee wrappee, String meth, Object[] args, int rk ) {
counter += wrappee.getClass().getDeclaredField(field).get(wrappee);
return wrappee.nextWrapper( meth, args, rk );
}
}
4.1.2 Authentication aspect
A simple means to implement an authentication aspect is to wrap the AgendaClient instances
withaclient-sidewrapperthataddstheagendaIDinthecontextandtowraptheagendaswitha
server-sideauthenticationwrapperthatwillreadthecontexttocheckiftheclientaccessestheright
agenda. Notice that theserver-sideauthenticationwrapperthrowsanexception in thecase the
authenticationfails. Thisisagoodexampletoillustratetheuseof(1)exceptionhandlers(dened
hereattheclient-side),and(2)contexts. Thefollowingclass denestheaddAuthInfos wrapping
methodand thecatchAuthenticationExceptionexceptionhandlerforAgendaClientinstances.
public class ClientAuthenticationWrapper {
public Object
addAuthInfos( Wrappee wrappee, String meth, Object[] args, int rk ) {
JacObject.getContext().addAttribute( "clname", args[0] );
return wrappee.nextWrapper( method, args, rk );
}
public void catchAuthenticationException( AuthenticationException e ) {
System.out.println( e.printStackTrace() );
}
makeAppointmentmethodtonotifytheotheragendasthatacommonappointmenthasbeentaken,
itimpliesthattheserver-sideauthenticationwrappermustbeskippedifthemakeAppointment is
calledbyanagenda. Oncethis hasbeendonebythecheckAuthInfoswrappingmethodwecheck
whethertheclNameattributeispresentinthecontexttransmittedbytheAgendaclientandifso,
iftheclientis authorizedtoaccess thisagenda. Ifnot,wethrowanexceptionthat willbecatch
bytheexceptionhandlerdened previously.
public class ServerAuthenticationWrapper {
public Object
checkAuthInfos( Wrappee wrappee, String meth, Object[] args, int rk )
throws AuthenticationException {
if ( ! (JacObject.peekFrame(1)[0] instanceof Agenda) ) {
Object clientName = JacObject.getContext().getAttribute("clname");
if ( clientName == null ||
! clientName.equals(wrappee.getFieldValue("id")) ) {
throw new AuthenticationException(
clientName+" is not authorized to access "+meth );
}
return wrappee.nextWrapper( method, args, rk );
}
}
4.2 Weaver
TheweaveristhepartofaJACprogramthatweavestheaspectstothebaseprogram,i.e. deploys
the aspect objectson the base objects. For example, the following weaver weavesthe counting
and theauthenticationaspects to abase program that containsseveral instances ofthe Agenda
andAgendaClient classes.
public class AgendaWeaver extends Weaver {
// Some information to parameterize the join-points
String calledMethod = "printAppointment";
String callingMethod = "printAppointments";
String field = "appointments";
String authenticatedMethods =
{ "makeAppointment", "printAppointment", "printAppointments" };
String clientMethods = { "makeAppointment" };
public void weave() {
Object[] agendas = JacObject.getObjects(Agenda.class);
Object[] clients = JacObject.getObjects(AgendaClient.class);
// create a server authentication wrapper
ServerAuthenticationWrapper saw = new ServerAuthenticationWrapper();
// create a server authentication wrapper
for ( int i=0 ; i < agendas.length ; i++ ) {
// create one counting wrapper per agenda
CountingWrapper cw = new CountingWrapper( calledMethod, callingMethod, field );
agendas[i].wrap( cw, "incr", calledMethod );
agendas[i].wrap( cw, "countWithField", callingMethod );
agendas[i].wrap( saw, "checkAuthInfos", authenticatedMethods );
}
// wrap the clients to add authentication
for ( int i=0 ; i < clients.length ; i++ ) {
agendas[i].wrap( caw, "addAuthInfos", clientMethods );
}
}
}
Furthermore,wespecify with thefollowingconguration le that the weavingis to be done
ontherstmethod callontherstinstanceoftheAgendaClient class(seesection3.4fordetails
aboutthispropertyle).
jac.weaver: AgendaWeaver
jac.startWeavingPlace: AgendaClient any 0 0
4.3 Composition aspect
In most common cases, the authentication must be applied rst. Indeed, it is quite clear that
any request to anobject must beauthenticated before any job is perform and even before any
otheraspectisrunned. Thusweneedtoimplementarulethatforcestheauthenticationaspectto
becalled before anyotheraspect. Thewrapping controllerthat performs thisweave-timecheck
follows(seemethod beforeWrap). It also checksthat theauthenticationwrapperis applied only
oncetothesamebaseobject.
This wrappingcontrolleralso externalizes the countingwrapperoptimization rule described
insection 4.1.1. Bythis way,welettheaspectcodefreefromanypollutionandthecomposition
policycanbecentralizedwithinawell-boundedsoftwareentity.
public class MyWrappingController extends WrappingController {
/** beforeWrap deals with weave-time issues related to the composition aspect */
public int beforeWrap( Wrappee wrappee, String wrappee_method_name,
Wrapper wrapper, String wrapper_method_name,
int default_rank ) {
if ( wrappers.length > 0 &&
wrappers[0].getClass() == ServerAuthenticationWrapper.class ) {
// refuse to wrap authentication twice !
if ( wrapper.getClass() == ServerAuthenticationWrapper.class ) {
return -1;
}
// put the new wrapper after the authentication wrapper
return 1;
}
/** getNextWrapper deals with runtime issues related to the composition aspect */
String calledMethod = "printAppointment";
String callingMethod = "printAppointments";
public int getNextWrapper( Wrappee wrappee, String wrappee_method_name,
Object[] wrappers, Object[] methods, int rank ) {
// check if the calling method is "print"
if ( wrappee_method_name == calledMethod &&
JacObject.peekFrame(1)[0] == wrappee &&
JacObject.peekFrame(1)[1] == callingMethod &&
wrappers[rank] instanceof CountingWrapper ) )
// skip the wrapper!
return rank + 1; else return rank; } } 5 Performance issues
We now present some performance measurements about JAC. Section 5.2 discusses about an
ongoingdevelopmentthataimsatspeedinguptheexecutionofanaspect-orientedprogramwith
JAC.
5.1 JAC performance measurements
This sectionstudies thecost ofrunningan aspect-orientedprogram withJAC.As illustratedin
gure4,weneedoneregularinvocationto thewrappingcontrollerbefore choosingeachwrapper
andtwoinvocationsperwrappingmethod(onetocallit,andonewhenthenextWrapper method
iscalledbythewrapper).
Thefollowing trace is the output of a benchmark program that creates an object and calls
100 times an empty method on it. It runs under JVM2 and Linux with a Pentium 300 MHz
processor. Theprogramperformsnothing,objectsareregularJavaobjects,theyarenottranslated
byJavassist,andthereisnoweavingbyJAC.Wejustrunittogettheamountoftimetakenby
theJVMto dothisjob.
>>> start time: 981972594672 ms
>>> end of class loading: +639 ms [duration: 639 ms]
>>> end of benchmark: +1242 ms [duration: 588 ms]
To test the overload due to the wrapping mechanism, we implement an empty aspect that
wrapsthe base objectwith 10empty wrappersand adds awrappingcontroller that is upcalled
but doesnotchangethe wrappersordering. Note that 10 wrappersisquite ahuge numberand
wedon'texpectsuchacasetobeencountered(1,2or3aspectsseemstobeamoreadequatecase
forthenearfuture). ThesameprogramrunningwithJACproducesthefollowingtrace.
>>> start time: 981973419075 ms
>>> end of benchmark: +6249 ms [duration: 4663 ms]
Theoverheadofthedynamicapplicationof10wrappers(evenempty)whenthebasemethod
iscalled 100timeis huge: 4663ms against588ms. Thisis nosurpriseaswereplaced callsto 1
baseobjectwithcalls thatgo through10wrapperobjectsand1baseobject. Thisroughlygives
usanoverheadof4msperbasecallperwrapper. Therstdurationgivesthetimeneededtoload
theclassesandadaptthemwithJavassist. Comparedtothepreviouscasewheretheclasseswhere
loaded with thestandard classloader of the JVM,the duration is multiplied by 2.4. Toreduce
it, JAC proposesa startingoptionthat writes theresultof theclass translationin atemporary
directory sothat, at the nextstart of the application, the class will not be translated anymore
(unlessweexplicitlyrequireit). Whenthetranslatedclassesare stored,theresult isalmost the
samethanwhennotranslationoccurs(655msagainst639ms).
>>> start time: 981973903301 ms
>>> end of class loading/translating: +655 ms [duration: 655 ms]
>>> end of weaving: +755 ms [duration: 100 ms]
This givesus asimplemeantooptimizeclasstranslation. Thesecond overheadalready
men-tioned(4663msagainst588when10wrappersareinsertedbefore100calls to1baseobject)can
onlybeovercomeiffewerwrappersareused. Wearein theprocess ofworkingon amechanism
that wecall wrapper aggregation that dynamicallyaggregatesthewholewrappingchainand the
wrappee intoone uniqueobject. Each methodofthis aggregationisconstructingby inliningthe
bytecodeofwrappingmethodsandofthewrappedmethod(notethatitalsoaggregatesthestates
of the wrappers and of the base object; this mechanism induces some state consistency issues
betweentheaggregationsandtheregularobjectsbutwewillnotenterintodetailshere). Bythis
way,wecanexpectthecostofrunningaapplicationweavedby10aspectstobegreatlyimproved.
Nextsectionexplainshowwecandealwiththesecondoverhead(whichcomesfromthe
wrap-pingmechanism).
5.2 Optimizing aspects with JAC
Todeal with the performance issue, wecurrentlywork on proposing amechanismthat we call
wrapper aggregation andthatdynamicallyaggregatesthewholewrappingchainandthewrappee
into one uniqueobject. Each method of this aggregationis composed by inlining the bytecode
ofthesetof thewrappingmethods andofthewrappedmethod (notethatitalsoaggregatesthe
states of the wrappers and of the base object; this mechanism induces some state consistency
issuesbetweentheaggregationsandtheregularobjectsbut wewillnotenterinto detailshere).
Whenanaggregationisavailable,theonlyre ectivecallistheonethatdelegatestheworkto
the aggregation. Moreover,contraryto regularwrappersthat use the java.lang.re ect package,
theaggregationwrappersperformdirectaccesstothewrappeestateandthusrunmoreeÆciently.
The aggregation creation mechanism is eÆcient since it does not requireany bytecode loading
becausealltheinvolvedbytecodesarealreadyloadedwithin theVM(westorethemin ourJAC
classloader).
Since the JAC framework cleanly separates the composition aspect from the other aspects,
these optimizationscanbecontext-sensitiveandbereallyeÆcient. Forexample,ifitappearsin
the wrapping controller that the wrappers order does not depend on the context, then we can
aggregatethewrappingchainonceandneverusethedynamicwrappingmechanismanymore. Of
course,ifthewrappingchain changesat runtime(in thiscasethewrappingcontrolleris notied
thankstothebeforeWrap method)thentheaggregationshould bereplacedbyanewone.
Thefollowingcodeshowshowtooptimizethedocumentexample. Dependingon thecontext
(whether the calling method is printAll or not), the whole wrapping chain is replaced by an
aggregationthatcontainsornotthecountingwrapper. Withthismethod,thecontexttestisdone
onlyonce andtheappropriateaggregatedwrappingchainis calledveryeÆciently(anaggregate
was not centralized within the wrapping controller. Indeed, if the composition information is
hardcoded within the aspect codes, then the context-sensitivetests would be always performed
foralltheaspects evenifnotneeded.
public class EfficientCountingWrappingController
extends CountingWrappingController {
Object noSkipAggregate = null;
Object skipAggregate = null;
public int getNextWrapper (
Wrappee wrappee, String wrappee_method_name,
Object[] wrappers, Object[] methods, int rank ) {
if ( skipAggregate == null ) {
// create the aggregate and memorize it in the wrappee
skipAggregate = wrappee.createAggregate(
getWrappersWithSkip(wrappers, CountingWrapper.class) );
}
if ( noSkipAggregate == null ) {
// create the aggregate and memorize it in the wrappee
noSkipAggregate = wrappee.createAggregate(
getFullWrappingChain(wrappers));
}
// check if the calling method is "print"
if ( wrappee_method_name == calledMethod &&
JacObject.peekFrame(1)[0] == wrappee &&
JacObject.peekFrame(1)[1] == callingMethod ) {
// call the aggregate (this stops the current wrapping
// chain evaluation) wrappee.callAggregate(skipAgregate); } else { wrappee.callAggregate(noSkipAgregate); } } }
Thefollowingtraceisforthesamebenchmarkastheonedescribedinsection5.1butwehave
added a wrapping controller that aggregates the wrapping chain of the ten wrappers into one
uniqueaggregation 2
. It showsthat theoverhead(oneregularcalltothewrappingcontroller,one
re ective call and one aggregation creation) makes the JAC program less than one and a half
slowerthan the pure Javaversion. This is, to us, anexcellent tradeo regarding the exibility
JACfurnishesatruntime(moreover,oncetheaggregationsarecreated,theircreationoverheadis
notsensibleanymore).
>>> start time: 981983417636 ms
>>> end of class loading: +648 ms [duration: 648 ms]
>>> end of weaving: +747 ms [duration: 99 ms]
>>> end of aggregation creation: 848 ms [duration: 101 ms]
>>> end of benchmark: +1543 ms [duration: 695 ms]
2
Notethatouraggregatingsystemiscurrentlyaworkinprogressandisnotyetavailable.However,theprogram wemadeisaquitefaithfulsimulationofwhatwillhappenwhenanaggregationoccurs.
In [BW00], Buchi and Weck designed a mechanism called generic wrappers. Generic wrappers
are type safe and support modular reasoning. Their focus is oriented towards the denition of
reusable and composable components implemented bydierentvendors. Type soundnessis one
oftheirmainconcerns. Multiplewrappersforasinglewrappeecanbedened intheirapproach.
Nevertheless, their system does not dynamically manage the execution order of wrappers in a
wrappingchainasourwrappingcontroldoes.
Thecompositionlterobjectmodel[BA01](CFOM)isanextensiontotheconventionalobject
modelwhereinputandoutputlterscanbedenedtohandlesendingandreceivingofmessages.
This model is implemented for several languages, including Smalltalk, C++ and Java [Wic99].
Thelatterimplementationis anextensionto theregularJavasyntaxwhere keywordsareadded
to declare, for instance, lters attached to classes. The goalsof this model and ours are rather
similar: tohandleseparationofconcernsatameta level. Nevertheless,JACdoesnotrequireany
languageextension(i.e. wrappersandwrappeesarewritteninregularJava).
AspectJ [KHH +
01] is a powerful languagethat provides support for the implementation of
crosscuttingconcernsthroughpointcuts(collections ofprinciplepointsin theexecutionofa
pro-gram), andadvices (method-likestructuresattached to pointcuts). Precedencerulesare dened
when morethan one advice apply at ajoin point. Inmany features (e.g. pointcuts denition)
AspectJhasarichand vast semantics. Nevertheless, weargue thatin many casesthatwehave
studied, simpleschemessuchasthewrappingtechniqueproposedbyJACaresuÆcientto
imple-mentabroadrangeofsolutionsdealingwithseparationofconcerns.
Aspectual components[LLM99] and theirdirect predecessors adaptativeplug and play
com-ponents [ML98][MSL01] dene patternsof interaction, called participant graphs(PG), that
im-plementaspectsforapplications. PGscontainparticipantsroles(e.g. publishersandsubscribers
in apublish/subscribeinteractionmodel)that, (1)expect featuresabouttheclassesuponwhich
theywillbemapped,(2)mayreimplementfeatures,and(3)providesomelocalfeatures. PGsare
then mapped onto class graphswith entities called connectors, that dene thewayaspectsand
classesarecomposed. Aspectualcomponentscanbecomposedbyconnectingpartoftheexpected
interface of onecomponent to partof the provided interface of another. Nevertheless, it seems
thatbydoingso,thedenitionof thecomposition crosscutsthedenitionoftheaspects,loosing
bythis waytheexpected benetsofAOP.The approach takenin JACconsistsin modularizing
thiscrosscutingconcern(i.e. inter-aspectscomposition)in theso-calledwrappingcontroller(see
section4.3).
Subjectoriented programming[HO93][OKH +
95](SOP) anditsdirect successortheHyper/J
tool [TOHS99], provide the ability to handle dierent subjective perspectives, called subjects,
onthe problem tomodel. Subjectscan becomposed usingcorrespondencerules (specifying the
correspondences betweenclasses,methods, eldsof dierentsubjects), combinationrules(giving
thewaytwosubjectscanbegluedtogether,andcorrespondence-and-combinationrulesthat mix
bothapproaches. Prototypeimplementations of SOPfor C++ andSmalltalk exist,and amore
recent version for Java called Hyper/J is available. This latter tool implements the notion of
hyperspace[OT01] thatpermitsthe explicit identication ofany concernsof importance.
JAC also shares some caracteristics with other research projects. [Bus00] propose an
ev-ent/actionmodeltocomposeaspectsinaCORBAenvironment. Stillrelatedtotheevent/action
paradigm,Douence&al.[DMS01]areinterestedinformalizingthenotionofcrosscut. [BSLR98]
studiesthenotionofcompatibilitybetweenaspectsandmeta-classes. TheJavaPod[BR01]
plat-form for adaptable components oers an heritance like mechanism to extend object with
non-functionalproperties.
WethinkthatJACcoversaeldthat,uptoourknowledge,isnotfullyandcleanlyaddressed
byanyofthesesolutions:dynamicorderingofaspectprogramsandcontext-sensitiveoptimizations
withinthecompositionaspect. JACiswidelyinspiredfromtheLasagneabstractmodel[TVJ +
01]
that denes some concepts to achieve dynamic and context-sensitive selection of collaboration
renementsdependingon theclientof theapplication (but that is less exible sinceit doesnot
Separationofconcernsisoneofthemajorrequirementsformodernapplications. Flexibilityand
dynamicevolutionarealsoneededmostofthetime. Inthispaper,wepresenttheJACframework
that meets both needs by using the notion of wrapping controller to implement a composition
aspect. To xthe ideas,gure2summed uphowalltheJACparts interoperatewhenbuilding
anaspect-orientedapplication. JACtakesadvantageof theJavassist[Chi00]load-timeMOPto
transparentlyimplementtheneededgluebetweenaspectandapplicationprograms.
It is to notice that, contraryto AspectJ [KHH +
01] that focuses onthe pointcuts expression
with a new language, wemainly focus on the denition of a generic architecture for AOP. We
believethat wehavereachedmanyof thedesirablepropertiesneededbyaspect-orientedsystem
andlanguagesandthatourframeworkcanbelateroncoupledwithamorehigh-levellanguagein
ordertofacilitatetheprogrammertask. Thefollowinglistsummarizesthemainfeaturesprovided
byJAC.
ThebaseprogramiswritteninregularJava,canbelaunchedindependentlyfromtheaspects,
andthesourcecodeisnotneededfortheweaving.
Aspect programmingdoesnotrequireanysyntacticalextension. AspectobjectswithJAC
contains methods that can be either wrapping methods (that provides the ability to run
before, after, and around code), role methods (that introduce new features in application
objects), or exception handlers. Compared to AspectJ they can be seen as pure advice
entities. AspectobjectsinJACremainfreefromanydeploymentorcompositionissuesthat
arecompletelyhandledbytheweaverandthewrappingcontroller. Inoursense,thismakes
aspectprogramsmoregenericandmorereusable.
The weaveris aregular Javaprogramthat uses introspectionfeatures so that anykindof
crosscutting schemescan be implemented. The weaveris responsiblefor deployingaspect
objects onto application objects. So it denes the way aspects are composed with
appli-cations. Several wrapping methods canwrap agiven application method creating bythis
way, wrapping chains. Several role methods and exception handlers can also be attached
to a givenapplication object. Furthermore,the weaverisnotied when anew instanceof
a base class is created so that the aspect canbe extended in the mean time of the base
program extension. Assuming sometransactionalfeatures, aspects couldalso be smoothly
added andremovedat runtime,withoutstoppingtheapplication. Theweavingmechanism
is object-based and is well-tted to distributed programming since the modication of a
giveninstance donotnecessaryaect theotherclassinstances (thusallowingheterogenous
environments).
The wrapping controller is a regular Java program that externalizes aspect composition.
It allowscontext-sensitivemodicationsof the wrapping chains. This composition aspect
should beprogrammed by aprogrammer that knows about the whole set of aspects that
canbewoventotheapplication. Themainadvantagesofthisfeaturearetogreatlysimplify
theprogrammingoftheweaver(thatjusthandlesthedeploymentofaspectobjects)andof
aspectobjects(thatjust performcorefunctionalities). Thislast propertyallowstheaspect
programmer to produce much moregeneric and reusable aspect code than it would be if
s/he hadtodealwiththeaspectcompositionissue.
The JAC framework is used by the "Ecole Centrale de Lille" Laboratory to implement the
software part of the CarVia application that consists in controlling electronic devices via the
power-linenetwork. JACiscurrentlyunderevaluationbyAlcatelResearchtoimplementasecurity
aspectwithinanetworkmanagementplatform. JAChasalsobeenusedtoimplementtheLasagne
abstract model [TVJ +
01] and a distributed agenda management application. These concrete
projectstend toprovethat theJACframeworkallowstheprogrammer to producehigh quality
andeasilymaintainable code. Duringthedevelopmentprocessoftheseapplications,thebenets
asless dynamic aspect-orientedframeworks. Wewill also study thecomposition aspect to nd
out some recurrent patterns and useful abstractions so that we can propose a more high-level
programminginterfacetodealwiththisissue. Thepurposeofthisworkistomakethecomposition
processasautomaticaspossible.
References
[BA01] L.Bergmans andM.Aksit. Software Architectures andComponent Technology: The
StateoftheArtinResearchandPractice,chapterConstructingReusableComponents
withMultipleConcernsUsingCompositionFilters.KluwerAcademicPublishers,2001.
[BMV00] J. Brichau, W. De Meuter, and K. De Volder. Jumping aspects. Presented at the
ECOOP2000workshoponAspectsandDimensionsofConcerns,June2000.
http://trese.cs.utwente.nl/Workshops/adc2000/.
[BR01] E. Bruneton and M. Riveill. Experimentswith javapod, aplatform designedfor the
adaptation ofnon-functional properties. InProcedings of Re ection'01,volume 2192
ofLectureNotesinComputer Science,pages52{72.Springer,September2001.
[BSLR98] N. Bouraqadi-Saadani,T. Ledoux, and F. Rivard. Safe metaclass programming. In
Proceedings of the 13thConference on Object-OrientedProgramming: Systems,
Lan-guages andApplications (OOPSLA'98),volume33ofSIGPLANNotices.ACMPress,
October1998.
[Bus00] L.Bussard.Towardsapragmaticcompositionmodelofcorbaservicesbasedonaspectj.
InWorkshop ontheAspectsandDimensionsofConcernsatECOOP'2000,June2000.
http://trese.cs.utwente.nl/Workshops/adc2000/.
[BW00] M. Buchi and W. Weck. Generic wrappers. In Proceedings of the 14th European
Conference on Object-Oriented Programming (ECOOP'00), volume 1850 of Lecture
Notesin ComputerScience,pages201{225.Springer,June2000.
[Chi00] S.Chiba. Load-timestructuralre ectioninJava.InProceedings ofthe14thEuropean
Conference on Object-Oriented Programming (ECOOP'00), volume 1850 of Lecture
Notesin ComputerScience,pages313{336.Springer,June2000.
[DMS01] R.Douence,O.Motelet,andM.Sudholt.Aformaldenitionofcrosscut.InProcedings
of Re ection'01,volume 2192 of Lecture Notesin Computer Science, pages 170{186.
Springer,September2001.
[HO93] W.HarrisonandH.Ossher.Subject-orientedprogramming(Acritiqueofpureobjects).
InProceedings of OOPSLA'93,volume28ofSIGPLANNotices,pages411{428.ACM
Press,October1993.
[JAC] JAC. TheJACprojecthomepage. http://cedric.cnam.fr/caolac/jac/.
[KHH +
01] G. Kiczales, E. Hilsdale, J. Hugunin, M. Kersten, J. Palm, and W. Griswold. An
overview of AspectJ. In Proceedings of the 15th European Conference on
Object-OrientedProgramming(ECOOP'01),volume2072ofLecture Notesin Computer
Sci-ence,pages327{353.Springer,June2001.
[KLM +
97] G. Kiczales, J. Lamping, A. Mendhekar, C. Maeda, C. Lopes, J.M. Loingtier, and
J.Irwin. Aspect-orientedprogramming. InProceedings of the11th European
Confer-enceonObject-OrientedProgramming(ECOOP'97),volume1241ofLectureNotesin