Embed
Email

aspectj tutorial oopsla2004

Document Sample
aspectj tutorial oopsla2004
Shared by: HC111110051613
Categories
Tags
Stats
views:
1
posted:
11/9/2011
language:
Hungarian
pages:
116
Aspect-Oriented Programming

with AspectJ™





Julie Waterhouse

and

Mik Kersten



eclipse.org/aspectj

IBM

UBC

outline



• I AOP and AspectJ overview

– problems, basic concepts, context

• II AspectJ tutorial

– first example

– language mechanisms

– using aspects

• III examples and demo

• IV conclusion





2

CASCON '04

good modularity

XML parsing









• XML parsing in org.apache.tomcat

– red shows relevant lines of code

– nicely fits in one box

3

CASCON '04

good modularity

URL pattern matching









• URL pattern matching in org.apache.tomcat

– red shows relevant lines of code

– nicely fits in two boxes (using inheritance)

4

CASCON '04

problems like…

logging is not modularized









• where is logging in org.apache.tomcat

– red shows lines of code that handle logging

– not in just one place

– not even in a small number of places

5

CASCON '04

problems like…

session expiration is not modularized

ApplicationSession StandardSession

/* public void inva lidat e() { package org. apac he.to mcat. sessi on; /**

* ==== ===== ==== ===== ===== ===== ===== ==== ===== ===== ===== ===== ==== ===== == serv erSe ssion .remo veApp licat ionS essio n(con text) ; /** * Bind an o bject to t his s essio n, u sing the s pecif ied n ame. If an ob ject

* * Retur n th e Ht tpSes sion fo r whi ch th is * of th e sa me na me is alre ady b ound to t his s essio n, th e ob ject is

* The Apach e So ftwar e Lic ense, Vers ion 1.1 // r emov e eve rythi ng in the sess ion import java. io.I OExce ption ; object * repla ced.

* import java. io.O bject Input Strea m; * is th e fa cade. *

* Copy right (c) 1999 The Apach e Sof twar e Fou ndati on. All r ight s Enum erat ion e num = valu es.ke ys() ; import java. io.O bject Outpu tStre am; */ * After thi s met hod e xecut es, a nd i f the obje ct im pleme nts

* rese rved. whil e (e num.h asMor eElem ents( )) { import java. io.S erial izabl e; pub lic H ttpS essio n get Sessi on() { * Htt pSess ionBi nding Liste ner, th e con taine r ca lls

* Stri ng na me = (Stri ng)en um.n extEl ement (); import java. util .Enum erati on; * val ueBou nd() on the objec t.

* Redi strib utio n and use in so urce and binar y for ms, w ith o r wi thout remo veVal ue(na me); import java. util .Hash table ; retu rn ( (Http Sessi on) t his); *

* modi ficat ion, are permi tted provi ded that the f ollow ing c ondi tions } import java. util .Vect or; * @para m na me Na me to whic h the obj ect i s bou nd, c annot be null

* are met: import javax .ser vlet. Servl etExc eptio n; } * @para m va lue O bject to b e bou nd, canno t be null

* vali d = false ; import javax .ser vlet. http. HttpS essio n; *

* 1. R edist ribu tions of s ource code mus t ret ain t he ab ove c opyr ight } import javax .ser vlet. http. HttpS essio nBin dingE vent; * @exce ptio n Ill egalS tateE xcept ion if th is me thod is ca lled on a n

* n otice , th is li st of cond ition s an d the foll owing disc laim er. import javax .ser vlet. http. HttpS essio nBin dingL isten er; // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- - * inva lida ted s essio n

* pub lic b oole an is New() { import javax .ser vlet. http. HttpS essio nCon text; Session Publ ic M ethod s *

* 2. R edist ribu tions in b inary form mus t rep roduc e the abov e co pyrig ht if ( ! va lid) { import org.a pach e.tom cat.c atali na.*; * @depr ecat ed As of V ersio n 2.2 , th is me thod is re place d by

* n otice , th is li st of cond ition s an d the foll owing disc laim er in Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.se ssio n.ise "); import org.a pach e.tom cat.u til.S tring Mana ger; * se tAttr ibute ()

* t he do cume ntati on an d/or other mat erial s pro vided with the /** */

* d istri buti on. thro w new Ille galSt ateEx cept ion(m sg); * Updat e th e acc essed time info rmat ion f or th is se ssion . pub lic v oid putVa lue(S tring name , Ob ject value ) {

* } /** This me thod

* 3. T he en d-us er do cumen tatio n inc lude d wit h the redi strib utio n, if * Stan dard impl ement ation of t he Ses sion * shoul d be call ed by the conte xt w hen a requ est c omes in setA ttri bute( name, valu e);

* a ny, m ust inclu de th e fol lowin g ac knowl egeme nt: if ( this Acces sTime == c reati onTi me) { interfa ce. This obje ct is for a p artic ular

* "Th is p roduc t inc ludes soft ware deve loped by t he retu rn tr ue; * seri aliza ble, so t hat i t can be s tore d in * sessi on, even if th e app licat ion does not r efere nce i t. }

* Ap ache Soft ware Found ation (ht tp:// www.a pache .org/ )." } el se { persist ent s tora ge or tran sferr ed */

* A ltern atel y, th is ac knowl egeme nt m ay ap pear in th e sof twar e retu rn fa lse; * to a diff eren t JVM for distr ibuta ble sessi on pub lic v oid acces s() {

itself, } support . /**

* i f and whe rever such thir d-par ty a cknow legem ents norma lly appea r. } * this .las tAcce ssedT ime = this .thi sAcce ssedT ime; * Remov e th e obj ect b ound with the speci fied name from this sess ion. If

* * I MPLEM ENTA TION NOTE: An i nsta nce o f thi s this .thi sAcce ssedT ime = Syst em.c urren tTime Milli s(); * the s essi on do es no t hav e an obje ct bo und w ith t his n ame, this meth od

* 4. T he na mes "The Jakar ta Pr oject ", " Tomca t", a nd "A pache Sof tware class r epres ents both the this .isN ew=fa lse; * does noth ing.

* F ounda tion " mus t not be u sed t o en dorse or p romot e pro duct s /** * inte rnal (Ses sion) and appli catio n le vel } *

derived * @depr ecat ed (HttpSe ssion ) vi ew of the sessi on. * After thi s met hod e xecut es, a nd i f the obje ct im pleme nts

* f rom t his softw are w ithou t pri or w ritte n per missi on. F or w ritte n */ * Howe ver, beca use t he cl ass i tself is not d eclar ed * Htt pSess ionBi nding Liste ner, th e con taine r ca lls

* p ermis sion , ple ase c ontac t apa che@ apach e.org . public, Java log ic ou tside /** * val ueUnb ound( ) o n th e obj ect.

* pub lic v oid putVa lue(S tring name , Ob ject value ) { * of t he org.a pache .tomc at.se ssio n * Perfo rm t he in terna l pro cessi ng r equir ed to inva lidat e *

* 5. P roduc ts d erive d fro m thi s sof twar e may not be ca lled "Apa che" setA ttri bute( name, valu e); package cann ot c ast a n this se ssion , * @para m na me Na me of the objec t to remo ve fr om th is se ssio n.

* n or ma y "A pache " app ear i n the ir n ames witho ut pr ior w ritt en } * Http Sessi on v iew o f thi s ins tance bac k to a * witho ut t rigge ring an ex cepti on i f the sess ion h as *

* p ermis sion of t he Ap ache Group . Session view . already expi red. * @exce ptio n Ill egalS tateE xcept ion if th is me thod is ca lled on a n

* pub lic v oid setAt tribu te(St ring name , Obj ect v alue) { * */ * inva lida ted s essio n

* THIS SOFT WARE IS P ROVID ED `` AS IS '' A ND AN Y EXP RESSE D OR IMPL IED if ( ! va lid) { * @aut hor C raig R. M cClan ahan pub lic v oid expir e() { */

* WARR ANTIE S, I NCLUD ING, BUT N OT LI MITE D TO, THE IMPLI ED WA RRAN TIES Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.se ssio n.ise "); * @ver sion $Rev ision : 1.2 $ $D ate: 2000 /05/1 5 pub lic v oid remov eAttr ibute (Stri ng n ame) {

* OF M ERCHA NTAB ILITY AND FITNE SS FO R A PARTI CULAR PURP OSE A RE 17:54:1 0 $ // R emov e thi s ses sion from our manag er's activ e

* DISC LAIME D. IN NO EVEN T SHA LL TH E AP ACHE SOFTW ARE F OUNDA TION OR thro w new Ille galSt ateEx cept ion(m sg); */ session s sync hron ized (attr ibute s) {

* ITS CONTR IBUT ORS B E LIA BLE F OR AN Y DI RECT, INDI RECT, INCI DENT AL, } if ( (man ager != nu ll) & & (ma nage r ins tance of Obje ct ob ject = att ribut es.g et(na me);

* SPEC IAL, EXEM PLARY , OR CONSE QUENT IAL DAMAG ES (I NCLUD ING, BUT NOT final c lass Stan dardS essio n Manager Base) ) if ( objec t == null)

* LIMI TED T O, P ROCUR EMENT OF S UBSTI TUTE GOOD S OR SERVI CES; LOSS OF if ( name == n ull) { imp lemen ts H ttpSe ssion , Ses sion { ((Ma nager Base) mana ger). remo ve(th is); retur n;

* USE, DATA , OR PROF ITS; OR BU SINES S IN TERRU PTION ) HOW EVER CAUS ED AN D Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.va lue. iae") ; attr ibute s.rem ove(n ame);

* ON A NY TH EORY OF L IABIL ITY, WHETH ER I N CON TRACT , STR ICT L IABI LITY, // U nbin d any obje cts a ssoci ated with this sess ion // S ystem .out. print ln( "Remo ving attri bute " + name );

* OR T ORT ( INCL UDING NEGL IGENC E OR OTHE RWISE ) ARI SING IN AN Y WA Y OUT thro w new Ille galAr gumen tExc eptio n(msg ); // ----- ---- ----- ----- ----- ----- ---- ----- ----- --- Vect or r esult s = n ew Ve ctor( ); if ( objec t ins tance of Ht tpSe ssion Bindi ngLis tener ) {

* OF T HE US E OF THIS SOFT WARE, EVEN IF ADVIS ED OF THE POSSI BILI TY OF } ------- ----- - Co nstru ctors Enum erat ion a ttrs = get Attri bute Names (); ((Htt pSess ionBi nding List ener) obje ct).v alueU nbou nd

* SUCH DAMA GE. whil e (a ttrs. hasMo reEle ments ()) { ( new H ttpSe ssion Bind ingEv ent(( HttpS essio n) t his, name) );

* ==== ===== ==== ===== ===== ===== ===== ==== ===== ===== ===== ===== ==== ===== == remo veVa lue(n ame); // remov e an y exi sting bind ing Stri ng at tr = (Stri ng) a ttrs .next Eleme nt(); }

* /** resu lts.a ddEle ment( attr) ; }

* This soft ware cons ists of vo lunta ry c ontri butio ns ma de by man y if ( valu e != null && va lue i nsta nceof Http Sessi onBin ding Liste ner) { * Const ruct a ne w Ses sion assoc iate d wit h the }

* indi vidua ls o n beh alf o f the Apac he S oftwa re Fo undat ion. For more Http Sessi onBin dingE vent e = specifi ed Ma nage r. Enum erat ion n ames = res ults. elem ents( ); }

* info rmati on o n the Apac he So ftwar e Fo undat ion, pleas e see new H ttpSe ssion Bindi ngEv ent(t his, name) ; * whil e (n ames. hasMo reEle ments ()) {

* . * @para m ma nager The manag er wi th w hich this Stri ng na me = (Stri ng) n ames .next Eleme nt();

* ((Ht tpSes sionB indin gList ener )valu e).va lueBo und(e ); Session is a ssoc iated remo veAtt ribut e(nam e); /**

* [Add ition al n otice s, if requ ired by p rior licen sing condi tion s] } */ } * Remov e th e obj ect b ound with the speci fied name from this sess ion. If

* pub lic S tand ardSe ssion (Mana ger m anag er) { * the s essi on do es no t hav e an obje ct bo und w ith t his n ame, this meth od

*/ valu es.p ut(na me, v alue) ; // M ark this sessi on as inva lid * does noth ing.

} supe r(); setV alid (fals e); *

this .man ager = man ager; * After thi s met hod e xecut es, a nd i f the obje ct im pleme nts

/** } * Htt pSess ionBi nding Liste ner, th e con taine r ca lls

package org. apac he.to mcat. sessi on; * @depr ecat ed } * val ueUnb ound( ) o n th e obj ect.

*/ *

import org.a pach e.tom cat.c ore.* ; pub lic O bjec t get Value (Stri ng na me) { /** * @para m na me Na me of the objec t to remo ve fr om th is se ssio n.

import org.a pach e.tom cat.u til.S tring Mana ger; retu rn g etAtt ribut e(nam e); // ----- ---- ----- ----- ----- ----- ---- ----- ----- --- * Relea se a ll ob ject refer ences , an d ini tiali ze in stanc e *

import java. io.* ; } ------- Inst ance Vari ables variabl es, i n * @exce ptio n Ill egalS tateE xcept ion if th is me thod is ca lled on a n

import java. net. *; * prepa rati on fo r reu se of this obj ect. * inva lida ted s essio n

import java. util .*; pub lic O bjec t get Attri bute( Strin g na me) { */ *

import javax .ser vlet. *; if ( ! va lid) { /** pub lic v oid recyc le() { * @depr ecat ed As of V ersio n 2.2 , th is me thod is re place d by

import javax .ser vlet. http. *; Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.se ssio n.ise "); * The c olle ction of u ser d ata a ttri butes * re moveA ttrib ute()

associa ted w ith this Sessi on. // R eset the insta nce v ariab les assoc iated with this */

/** thro w new Ille galSt ateEx cept ion(m sg); */ Session pub lic v oid remov eValu e(Str ing n ame) {

* Core impl emen tatio n of an ap plica tion leve l ses sion } pri vate Hash table attr ibute s = n ew H ashta ble() ; attr ibut es.cl ear() ;

* crea tion Time = 0L; remo veAt tribu te(na me);

* @aut hor J ames Dunc an Da vidso n [du ncan @eng. sun.c om] if ( name == n ull) { id = nul l;









Sess on n ercep or StandardManager StandardSessionManager

* @aut hor J ason Hunt er [j ch@en g.sun .com ] Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.va lue. iae") ; /** last Acce ssedT ime = 0L; }

* @aut hor J ames Todd [gon zo@en g.sun .com ] * The t ime this sessi on wa s cre ated , in mana ger = nul l;

*/ thro w new Ille galAr gumen tExc eptio n(msg ); millise conds sin ce mi dnigh t, maxI nact iveIn terva l = - 1;

} * Janua ry 1 , 197 0 GMT . isNe w = true; /**

public class App licat ionSe ssion impl emen ts Ht tpSes sion { */ isVa lid = fal se; * Bind an o bject to t his s essio n, u sing the s pecif ied n ame. If an ob ject

retu rn v alues .get( name) ; pri vate long crea tionT ime = 0L; * of th e sa me na me is alre ady b ound to t his s essio n, th e ob ject is

pri vate Stri ngMan ager sm = } // T ell our M anage r tha t thi s Se ssion has been recyc led * repla ced.

Stri ngMa nager .getM anage r("or g.ap ache. tomca t.ses sion" ); if ( (man ager != nu ll) & & (ma nage r ins tance of *

pri vate Hash table valu es = new H asht able( ); /** /** Manager Base) ) * After thi s met hod e xecut es, a nd i f the obje ct im pleme nts

pri vate Stri ng id ; * @depr ecat ed * The s essi on id entif ier o f thi s Se ssion . ((Ma nager Base) mana ger). recy cle(t his); * Htt pSess ionBi nding Liste ner, th e con taine r ca lls

pri vate Serv erSes sion serve rSess ion; */ */ * val ueBou nd() on the objec t.

pri vate Cont ext c ontex t; pub lic S trin g[] g etVal ueNam es() { pri vate Stri ng id = nu ll; } *

pri vate long crea tionT ime = Syst em.c urren tTime Milli s();; Enum erat ion e = ge tAttr ibute Name s(); * @para m na me Na me to whic h the obj ect i s bou nd, c annot be null

pri vate long this Acces sTime = cr eati onTim e; Vect or n ames = new Vect or(); * @para m va lue O bject to b e bou nd, canno t be null package org. apac he.to mcat. sessi on; package org. apac he.to mcat. sessi on; // ---- ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- Pub lic

pri vate long last Acces sed = crea tion Time; /** // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- Sess ion * // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- - Li fecyc le Me thods Methods

pri vate int inact iveIn terva l = - 1; whil e (e .hasM oreEl ement s()) { * Descr ipti ve in forma tion descr ibin g thi s Package Meth ods * @exce ptio n Ill egalA rgume ntExc epti on if an a ttemp t is made to a dd a import java. io.I OExce ption ;

pri vate bool ean v alid = tru e; name s.add Eleme nt(e. nextE leme nt()) ; Session impl emen tatio n. * non- seri aliza ble o bject in a n en viron ment marke d dis trib utabl e. import java. util .Enum erati on; import java. io.I OExce ption ;

} */ * @exce ptio n Ill egalS tateE xcept ion if th is me thod is ca lled on a n import java. util .Hash table ; /**

import javax .ser vlet. http. Cooki e;

App licat ionS essio n(Str ing i d, Se rver Sessi on se rverS essio n, pri vate stat ic fi nal S tring info = /** * inva lida ted s essio n import java. util .Vect or; * Confi gure this comp onent , bas ed o n the spec ified conf igur ation

/**

Cont ext conte xt) { Stri ng[] valu eName s = n ew St ring [name s.siz e()]; "Standa rdSes sion /1.0" ; * Retur n th e is Valid f lag f or th is se ssion . */ import org.a pach e.tom cat.c atali na.*; * param eter s. T his m ethod shou ld b e cal led i mmedi ately aft er th e import javax .ser vlet. http. HttpS essio n;

this .ser verSe ssion = se rverS essi on; */ pub lic v oid setAt tribu te(St ring name , Obj ect v alue) { import javax .ser vlet. http. Cooki e; * compo nent inst ance is cr eated , an d bef ore start () * Mark the speci fied sessi on's last acce ssed time. Thi s sh ould be

import org.a pach e.tom cat.c atali na.*;

this .con text = con text; name s.co pyInt o(val ueNam es); boo lean isVa lid() { import javax .ser vlet. http. HttpS essio n; * is ca lled .

* calle d fo r eac h req uest by a Requ estIn terce ptor.

this .id = id; /** if ( (man ager != nu ll) & & man ager .getD istri butab le() && import org.a pach e.tom cat.u til.S tring Mana ger; * import org.a pach e.tom cat.c ore.C ontex t;

retu rn v alueN ames; * The l ast acces sed t ime f or th is S essio n. retu rn ( this. isVal id); !( valu e ins tance of Se riali zabl e)) import org.w 3c.d om.Na medNo deMap ; * @para m pa ramet ers C onfig urati on p arame ters for t his c ompo nent *

import org.a pach e.tom cat.c ore.R eques t;

this .ina ctive Inter val = cont ext. getSe ssion TimeO ut(); */ thro w new Ille galAr gumen tExc eptio n import org.w 3c.d om.No de; * ( FIXM E: Wh at ob ject type shou ld th is re ally be?)

* @para m se ssion The sessi on to be marke d

} pri vate long last Acces sedTi me = crea tionT ime; } (sm.g etStr ing(" stand ardS essio n.set Attri bute. iae" )); * import org.a pach e.tom cat.c ore.R espon se;

if ( this .inac tiveI nterv al != -1) { * @exce ptio n Ill egalS tateE xcept ion if th is co mpone nt ha s al ready been */

import org.a pach e.tom cat.c ore.S essio nMan ager;

this .inac tiveI nterv al *= 60; pub lic E nume ratio n get Attri buteN ames () { sync hron ized (attr ibute s) { /** * conf igur ed an d/or start ed

pub lic v oid acces sed(C ontex t ctx , Re quest req, Stri ng id ) {

} if ( ! va lid) { /** /** remo veAtt ribut e(nam e); * Stan dard impl ement ation of t he Man ager i nterf ace t hat provi des * @exce ptio n Lif ecycl eExce ption if this compo nent detec ts a fata l err or import org.a pach e.tom cat.u til.S essio nUti l;

} Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.se ssio n.ise "); * The M anag er wi th wh ich t his S essi on is * Set t he isNew fl ag f or th is se ssion . attr ibute s.put (name , val ue); * no s essio n pe rsist ence or di strib utab le ca pabil ities , but doe s sup port * in t he c onfig urati on pa ramet ers it wa s giv en Http Sess ion s essio n=fin dSess ion( ctx, id);

associa ted. * if ( value inst anceo f Htt pSes sionB indin gList ener) * an o ption al, confi gurab le, m aximu m nu mber of ac tive sessi ons allow ed. */

if( sess ion = = nul l) re turn;

Ser verSe ssio n get Serve rSess ion() { thro w new Ille galSt ateEx cept ion(m sg); */ * @para m is New T he ne w val ue fo r th e is New ((Htt pSess ionBi nding List ener) valu e).va lueBo und * pub lic v oid confi gure( Node param eter s)

retu rn s erver Sessi on; } pri vate Mana ger m anage r = n ull; flag ( new H ttpSe ssion Bind ingEv ent(( HttpS essio n) t his, name) ); * Life cycle con figur ation of t his c ompo nent assum es an XML node thro ws L ifecy cleEx cepti on { if ( sess ion i nstan ceof Sessi on)

/**

} */ } * in t he fo llow ing f ormat :

((Se ssion ) ses sion) .acce ss() ;

Hash tabl e val uesCl one = (Has htab le)va lues. clone (); voi d set New( boole an is New) { * // V alid ate a nd up date our c urre nt co mpone nt st ate * Spec ializ ed i mplem entat ion o f org .apa che.t omcat .core .Sess ionM anage r

/** /** } * <M anag er cl assNa me="o rg.ap ache .tomc at.se ssion .Stan dard Manag er" if ( conf igure d)

* that adap ts t o the new compo nent- base d Man ager imple menta tion .

* Calle d by cont ext w hen r eques t co mes i n so that acces ses and retu rn ( Enume ratio n)val uesCl one. keys( ); * The m axim um ti me in terva l, in sec onds, betw een this .isN ew = isNew ; * check Inter val=" 60" m axAc tiveS essio ns="- 1" thro w new Life cycle Excep tion

// c ache the HttpS essio n - a void anot her f ind

* inact ivit ies c an be deal t wit h ac cordi ngly. } client reque sts befor e * maxIn activ eInte rval= "-1" /> (sm.g etStr ing(" stand ardM anage r.alr eadyC onfig ured ")); *

*/ * the s ervl et co ntain er ma y inv alid ate t his } // ----- ---- ----- ----- ----- ----- ---- ----- ----- - Htt pSess ion Priva te Me thods * conf igur ed = true; req. setS essio n( se ssion );

* XXX - At pres ent, use o f St anda rdMan ager is hard code d,

session . A nega tive time * wher e you can adju st th e fol lowin g pa ramet ers, with defau lt v alues if ( para meter s == null)

}

voi d acc esse d() { /** * indic ates that the sessi on sh ould neve r tim e * in s quare bra ckets : retu rn; * and lifec ycle conf igura tion is no t su pport ed.

// s et l ast a ccess ed to this Acce ssTim e as it wi ll be lef t ove r * @depr ecat ed out. /** /** *

*

// f rom the p revio us ac cess */ */ * Set t he isVal id flag for this sessi on. * Read a se riali zed v ersio n of this sess ion o bject from the spec ified * ch eckI nterv al - T he in terv al (i n sec onds) betw een backg round // P arse and proce ss ou r con figu ratio n par amete rs

// XXX s houl d we throw exce ption or just retur n nul l ??

last Acce ssed = thi sAcce ssTim e; pri vate int maxIn activ eInte rval = -1 ; * * objec t in put s tream . * threa d ch ecks for e xpire d ses sion s. [ 60] if ( !("M anage r".eq uals( param eter s.get NodeN ame() ))) * I MPLEM ENTA TION NOTE: Once we commi t to the n ew

this Acce ssTim e = S ystem .curr entT imeMi llis( ); pub lic v oid remov eValu e(Str ing n ame) { * @para m is Valid The new v alue for the * * ma xAct iveSe ssion s - Th e ma ximum numb er of sess ions allo wed t o retu rn; Manager /Sess ion pub lic H ttpS essio n fin dSess ion( Cont ext c tx, S tring id ) {

remo veAt tribu te(na me); i sVali d flag * IM PLEM ENTAT ION N OTE: The refer ence to th e own ing Manag er * be ac tive at o nce, or -1 for no l imit. [-1 ] Name dNod eMap attri butes = pa rame ters. getAt tribu tes() ;

* para digm, I w ould sugge st mo ving the logic impl ement ed he re b ack i nto try {

vali date (); } /** */ * is no t re store d by this metho d, a nd mu st be set expli citl y. * ma xIna ctive Inter val - The defau lt ma ximum numb er o f sec onds of Node nod e = n ull;

} * Flag indi catin g whe ther this sess ion i s new or voi d set Vali d(boo lean isVal id) { * * inact ivit y bef ore w hich the s ervl et co ntain er is allo wed to ti me ou t * the core leve l. T he To mcat. Next "Man ager" inte rface acts mor e lik e a Sess ion s essio n = m anage r.fi ndSes sion( id);

pub lic v oid remov eAttr ibute (Stri ng n ame) { not. * @para m st ream The i nput strea m to read from * a ses sion , or -1 fo r no limit . T his v alue shoul d be over ridde n fro m node = a ttrib utes. getNa medIt em(" check Inter val") ;

* coll ectio n cl ass, and h as mi nimal kno wledg e of the d etail ed r eques t if(s essio n!=nu ll)

voi d val idat e() { if ( ! va lid) { */ this .isV alid = isV alid; * * the d efau lt se ssion time out s peci fied in th e web appl icat ion d eploy ment if ( node != n ull) {

// i f we have an i nacti ve in terv al, c heck to se e if we'v e exc eeded it Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.se ssio n.ise "); pri vate bool ean i sNew = tru e; } * @exce ptio n Cla ssNot Found Excep tion if a n unk nown class is speci fied * descr ipto r, if any. [-1 ] try { * proc essin g se manti cs of hand ling sess ions. retur n ses sion. getSe ssio n();

if ( inac tiveI nterv al != -1) { * @exce ptio n IOE xcept ion i f an inpu t/out put e rror occur s * setCh eckIn terva l(Int eger .pars eInt( node. getNo deVa lue() ));

* } ca tch (IOEx cepti on e) {

int thisI nterv al = thro w new Ille galSt ateEx cept ion(m sg); */ * } ca tch ( Throw able t) {

(int) (Syst em.cu rrent Time Milli s() - last Acces sed) / 10 00; } /** // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- - pri vate void read Objec t(Obj ectIn putS tream stre am) * @aut hor C raig R. M cClan ahan ; // XXX - Thr ow e xcept ion? * XXX - At pres ent, there is n o way (vi a the Sess ionMa nager int erfac e) }

* Flag indi catin g whe ther this sess ion i s val id HttpSes sion Prop ertie s thro ws C lassN otFou ndExc eptio n, I OExce ption { * @ver sion $Rev ision : 1.1 .1.1 $ $Da te: 2000/ 05/02 21:2 8:30 $ } for

retu rn ( null) ;

if ( thisI nterv al > inact iveI nterv al) { if ( name == n ull) { or not. */ }

* a Co ntext to tell the M anage r tha t we crea te wh at th e def ault sess ion

inval idate (); Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.va lue. iae") ; */ // D eser ializ e the scal ar in stan ce va riabl es (e xcept Man ager) }

} pri vate bool ean i sVali d = f alse; /** crea tion Time = ((L ong) strea m.re adObj ect() ).lon gValu e(); public final cla ss St andar dMana ger node = a ttrib utes. getNa medIt em(" maxAc tiveS essio ns"); * time out f or t his w eb ap plica tion (spe cifie d in the d eploy ment

} thro w new Ille galAr gumen tExc eptio n(msg ); * Retur n th e tim e whe n thi s ses sion was creat ed, i n id = (St ring) stre am.re adObj ect( ); ext ends Mana gerBa se if ( node != n ull) { descrip tor)

} } millise conds sin ce last Acce ssedT ime = ((Lo ng) s trea m.rea dObje ct()) .long Valu e(); imp lemen ts L ifecy cle, Runna ble { try { pub lic H ttpS essio n cre ateSe ssion (Con text ctx) {

* shou ld be .

/** * midni ght, Janu ary 1 , 197 0 GMT . maxI nact iveIn terva l = ( (Inte ger) stre am.re adObj ect() ).in tValu e(); setMa xActi veSes sions (Int eger. parse Int(n ode.g etNo deVal ue()) );

retu rn manag er.cr eateS essio n(). getSe ssion ();

// HTTP SESS ION I MPLEM ENTAT ION M ETHO DS Obje ct o = va lues. get(n ame); * The s trin g man ager for t his p acka ge. * isNe w = ((Boo lean) stre am.re adOb ject( )).bo olean Value (); } ca tch ( Throw able t) { *

*/ * @exce ptio n Ill egalS tateE xcept ion if th is me thod is isVa lid = ((B oolea n) st ream. read Objec t()). boole anVal ue() ; // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- Ins tance Vari ables ; // XXX - Thr ow e xcept ion? }

* @aut hor C raig R. M cClan ahan

pub lic S trin g get Id() { if ( o in stanc eof H ttpSe ssion Bind ingLi stene r) { pri vate Stri ngMan ager sm = called on an }

if ( vali d) { Http Sessi onBin dingE vent e = * inva lida ted s essio n // D eser ializ e the attr ibute cou nt an d att ribut e val ues } */

retu rn id ; new H ttpSe ssion Bindi ngEv ent(t his,n ame); StringM anage r.ge tMana ger(" org.a pache .tom cat.s essio n") */ int n = ((Int eger) stre am.re adOb ject( )).in tValu e(); /** /**

} el se { ; pub lic l ong getCr eatio nTime () { for (int i = 0; i * The d escr iptiv e inf ormat ion a bout this impl ement ation . // c onte xts, we ju st wa nt to rem ove t he se ssion s of ctx!

/**

thro w new Ille galSt ateEx cept ion(m sg); */ * repl acem ent. It w ill b e rem oved in a futu re ve rsion of * IM PLEM ENTAT ION N OTE: The ownin g Man ager will not be st ored */

// T he m anage r wil l sti ll ru n af ter t hat ( i.e. keep dat abase

} inac tive Inter val = inte rval; pri vate long this Acces sedTi me = crea tionT ime; the * in th e se riali zed r epres entat ion of th is Se ssion . Af ter calli ng pri vate stat ic fi nal S tring info = " Stand ardMa nager /1.0" ; /** * Creat e a new S essio nMana ger t hat adapt s to the c orres pond ing

} } * Java Ser vlet API. * rea dObje ct(), yo u mu st se t the asso ciate d Ma nager * Prepa re f or th e beg innin g of acti ve us e of the p ublic met hods of th is Manager // c onne ction open

*/ * expli citl y. * compo nent . Th is me thod shoul d be call ed af ter conf igure (),

* imple ment ation . if ( mana ger i nstan ceof Lifec ycle ) {

/** pub lic i nt g etMax Inact iveIn terva l() { pub lic H ttpS essio nCont ext g etSes sion Conte xt() { * /** * and b efor e any of t he pu blic meth ods o f the comp onent are util ized.

* if ( ! va lid) { * IM PLEM ENTAT ION N OTE: Any attri bute that is no t Se riali zable * The m axim um nu mber of ac tive Sess ions allow ed, o r -1 for no li mit. * */ try {

* @depr ecat ed Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.se ssio n.ise "); // ----- ---- ----- ----- ----- ----- ---- ----- ----- --- if ( sess ionCo ntext == n ull) * will be s ilent ly ig nored . If you do n ot wa nt an y suc h at tribu tes, */ * @exce ptio n Ill egalS tateE xcept ion if th is co mpone nt ha s no t yet been

pub lic S tand ardSe ssion Manag er() { ((Lif ecycl e) ma nager ).st op();

*/ ------- Sess ion Prope rties sess ionCo ntext = ne w Sta ndar dSess ionCo ntext (); * be su re t he d istri butab le prop erty of ou r as socia ted pro tecte d in t max Activ eSess ions = -1 ; * conf igur ed (i f req uired for this comp onent )

thro w new Ille galSt ateEx cept ion(m sg); retu rn ( sessi onCon text) ; * Manag er i s set to true. * @exce ptio n Ill egalS tateE xcept ion if th is co mpone nt ha s al ready been } ca tch ( Lifec ycleE xcept ion e) {

pub lic H ttpS essio nCont ext g etSes sion Conte xt() { } * * star ted

mana ger = new Stan dardM anage r(); throw new Illeg alSta teEx cepti on("" + e) ;

retu rn n ew Se ssion Conte xtImp l(); /** } * @para m st ream The o utput stre am t o wri te to /** * @exce ptio n Lif ecycl eExce ption if this compo nent detec ts a fata l err or

} retu rn i nacti veInt erval ; * Set t he c reati on ti me fo r thi s se ssion . Th is * * The s trin g man ager for t his p acka ge. * that pre vents this comp onent fro m bei ng us ed if ( mana ger i nstan ceof Lifec ycle ) { }

} method is ca lled by t he * @exce ptio n IOE xcept ion i f an inpu t/out put e rror occur s */ */

try { }

pub lic l ong getLa stAcc essed Time( ) { } * Manag er w hen a n exi sting Sess ion insta nce i s // ----- ---- ----- ----- ----- ----- ---- ----- ----- --- */ pri vate Stri ngMan ager sm = pub lic v oid start () th rows Lifec ycle Excep tion {

if ( vali d) { reused. HttpSes sion Publ ic Me thods pri vate void writ eObje ct(Ob jectO utpu tStre am st ream) thro ws I OExce ption { Stri ngMa nager .getM anage r("or g.ap ache. tomca t.ses sion" ); ((Lif ecycl e) ma nager ).co nfigu re(nu ll);

retu rn la stAcc essed ; * // V alid ate a nd up date our c urre nt co mpone nt st ate

((Lif ecycl e) ma nager ).st art() ; }

} el se { //----- ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- ---- ----- ---- * @para m ti me Th e new crea tion time // W rite the scala r ins tance var iable s (ex cept Manag er) if ( !con figur ed)

Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.se ssio n.ise "); */ /** stre am.w riteO bject (new Long( crea tionT ime)) ; /** thro w new Life cycle Excep tion } ca tch ( Lifec ycleE xcept ion e) {

pub lic v oid setCr eatio nTime (long tim e) { * Retur n th e obj ect b ound with the speci fied name in th is stre am.w riteO bject (id); * Has t his compo nent been start ed y et? (sm.g etStr ing(" stand ardM anage r.not Confi gured "));

throw new Illeg alSta teEx cepti on("" + e) ; /**

thro w new Ille galSt ateEx cept ion(m sg); session , or stre am.w riteO bject (new Long( last Acces sedTi me)); */ if ( star ted)

} this .cre ation Time = tim e; * nul l i f no objec t is boun d wit h tha t nam e. stre am.w riteO bject (new Integ er(m axIna ctive Inter val)) ; pri vate bool ean s tarte d = f alse; thro w new Life cycle Excep tion } * Used by c ontex t to confi gure the sessi on ma nager 's in acti vity

} this .las tAcce ssedT ime = time ; * stre am.w riteO bject (new Boole an(i sNew) ); (sm.g etStr ing(" stand ardM anage r.alr eadyS tarte d")) ; timeout .

}

this .thi sAcce ssedT ime = time ; * @para m na me Na me of the attri bute to b e ret urned stre am.w riteO bject (new Boole an(i sVali d)); star ted = tru e;

*

* /**

} * @exce ptio n Ill egalS tateE xcept ion if th is me thod is // A ccum ulate the names of s eria lizab le at tribu tes * The b ackg round thre ad. // S tart the backg round reap er t hread * The S essi onMan ager may h ave s ome defau lt se ssion time out , the

}

called on an Vect or r esult s = n ew Ve ctor( ); */ thre adSt art() ;

* Conte xt o n the othe r han d has it' s tim eout set b y the dep loyme nt

* inva lida ted s essio n Enum erat ion a ttrs = get Attri bute Names (); pri vate Thre ad th read = nul l;

/** */ whil e (a ttrs. hasMo reEle ments ()) { } * descr ipto r (we b.xml ). Th is me thod lets the Conte xt co nfor gure the

* Retur n th e ses sion ident ifier for this pub lic O bjec t get Attri bute( Strin g na me) { Stri ng at tr = (Stri ng) a ttrs .next Eleme nt();

* sessi on m anage r acc ordin g to this valu e.

session . Obje ct va lue = attr ibute s.ge t(att r); /** // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- Ins tance

*/ retu rn ( attri butes .get( name) ); if ( value inst anceo f Ser iali zable ) * The b ackg round thre ad co mplet ion semap hore. /** Variabl es *

pub lic S trin g get Id() { resul ts.ad dElem ent(a ttr) ; */ * Grace full y ter minat e the acti ve u se of the publi c met hods of t his

* @para m mi nutes The sessi on in acti vity timeo ut in minu tes.

} } pri vate bool ean t hread Done = fal se; * compo nent . Th is me thod shoul d be the last one c alled on a giv en

retu rn ( this. id); * insta nce of th is co mpone nt. */

// S eria lize the a ttrib ute c ount and the attri bute valu es *

/** pub lic v oid setSe ssion TimeO ut(in t mi nutes ) {

} /** stre am.w riteO bject (new Integ er(r esult s.siz e())) ; /** * @exce ptio n Ill egalS tateE xcept ion if th is co mpone nt ha s no t bee n sta rted

* Retur n an Enu merat ion of Enum erat ion n ames = res ults. elem ents( ); * Name to r egist er fo r the back grou nd th read. * @exce ptio n Ill egalS tateE xcept ion if th is co mpone nt ha s al ready * The M anag er im pleme ntati on we are actu ally using . if(- 1 != minu tes) {

S tring o bject s whil e (n ames. hasMo reEle ments ()) { */ * been sto pped

*/ // T he ma nager work s wit h se conds ...

/** * conta inin g the name s of the o bjec ts bo und t o thi s Stri ng na me = (Stri ng) n ames .next Eleme nt(); pri vate Stri ng th readN ame = "Sta ndar dMana ger"; * @exce ptio n Lif ecycl eExce ption if this compo nent detec ts a fata l err or

* Set t he s essio n ide ntifi er fo r th is se ssion . session . stre am.wr iteOb ject( name) ; * that nee ds to be r eport ed pri vate Mana ger m anage r = n ull; mana ger.s etMax Inact iveIn terv al(mi nutes * 60 );

* * stre am.wr iteOb ject( attri bute s.get (name )); */

}

* @para m id The new s essio n ide ntif ier * @exce ptio n Ill egalS tateE xcept ion if th is me thod is } // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- ---- ---- Prope rties pub lic v oid stop( ) thr ows L ifecy cleE xcept ion {

*/ called on an }

pub lic v oid setId (Stri ng id ) { * inva lida ted s essio n // V alid ate a nd up date our c urre nt co mpone nt st ate

}

*/ } /** if ( !sta rted)

if ( (thi s.id != nu ll) & & (ma nage r != null) && pub lic E nume ratio n get Attri buteN ames () { * Retur n th e che ck in terva l (in sec onds) for this Manag er. thro w new Life cycle Excep tion

(m anag er in stanc eof M anage rBas e)) cro sscut inv alida te(St andar dSess ion s): s & (i nt ge tMaxI nact iveIn terva l() | */ (sm.g etStr ing(" stand ardM anage r.not Start ed")) ;

((Ma nager Base) mana ger). remo ve(th is); retu rn ( attri butes .keys ()); l ong g etCre atio nTime () | pub lic i nt g etChe ckInt erval () { star ted = fal se;

O bject getA ttri bute( Strin g) |

this .id = id; } E numer ation get Attri buteN ames( ) | retu rn ( this. check Inter val); // S top the b ackgr ound reape r th read

S tring [] ge tVal ueNam es() | thre adSt op();









ServerSess on

if ( (man ager != nu ll) & & (ma nage r ins tance of v oid i nvali date () | }

Manager Base) ) /** b oolea n isN ew() | // E xpir e all acti ve se ssion s

((Ma nager Base) mana ger). add( this) ; * Retur n th e obj ect b ound with the speci fied name in th is v oid r emove Attr ibute (Stri ng) | Sess ion sessi ons[] = fi ndSes sion s();

session , or v oid s etAtt ribu te(St ring, Obje ct)); /** for (int i = 0; i nul l i f no objec t is boun d wit h tha t nam e. * Set t he c heck inter val ( in se cond s) fo r thi s Man ager. Stan dardS essio n ses sion = (S tanda rdSes sion) sess ions [i];

* sta tic a dvic e(Sta ndard Sessi on s) : in valid ate(s ) { * if ( !sess ion.i sVali d())

* @para m na me Na me of the value to be re turne d befo re { * @para m ch eckIn terva l The new chec k int erval conti nue;

/** * if ( !s.is Valid ()) */ sess ion.e xpire ();

* Retur n de scrip tive infor matio n ab out t his * @exce ptio n Ill egalS tateE xcept ion if th is me thod is throw new Illeg alSta teEx cepti on pub lic v oid setCh eckIn terva l(int che ckInt erval ) { }

Session impl emen tatio n and called on an ( s.sm. getSt ring( "sta ndard Sessi on."









ServerSessionManager

* the c orre spond ing v ersio n num ber, in t he * inva lida ted s essio n + th isJoi nPoin t.met hodNa me this .che ckInt erval = ch eckIn terv al; }

format * + ". ise") );

* * @depr ecat ed As of V ersio n 2.2 , th is me thod is re place d } }

& lt;de scri ption >/ <v ersio n> ;. by } // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- --- Priva te Me thods

*/ * ge tAttr ibute ()

pub lic S trin g get Info( ) { */ /**

pub lic O bjec t get Value (Stri ng na me) { * Retur n de scrip tive infor matio n ab out t his M anage r imp leme ntati on an d /**

retu rn ( this. info) ; * the c orre spond ing v ersio n num ber, in t he fo rmat * Inval idat e all sess ions that have expi red.

retu rn ( getAt tribu te(na me)); } * < ;desc ripti on> ;/< ;ver sion& gt; . */

} */ pri vate void proc essEx pires () {

} pub lic S trin g get Info( ) {

// ---- ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- ---- - Pri vate Class long tim eNow = Sys tem.c urren tTim eMill is();

/** retu rn ( this. info) ; Sess ion sessi ons[] = fi ndSes sion s();

* Retur n th e las t tim e the clie nt s ent a requ est /**

associa ted w ith this * Retur n th e set of n ames of ob ject s bou nd to this /** package org. apac he.to mcat. sessi on; } for (int i = 0; i Ht tpSes sion Conte xt Stan dardS essio n ses sion = (S tanda rdSes sion) sess ions [i];

midnigh t, Ja nuar y 1, 1970 * are n o su ch ob jects , a z ero-l engt h arr ay is retu rned. * inte rface , to conf orm t o the requ irem ent t hat s uch a n obj ect be re turne d import org.a pach e.tom cat.u til.* ; if ( !sess ion.i sVali d())

* GMT. Act ions that your appli cati on ta kes, * * when Ht tpSes sion. getSe ssion Cont ext() is call ed. import org.a pach e.tom cat.c ore.* ; /** conti nue;

such as gett ing or se tting * @exce ptio n Ill egalS tateE xcept ion if th is me thod is * import java. io.* ; * Retur n th e max imum numbe r of acti ve Se ssion s all owed, or -1 fo r int maxIn activ eInte rval = se ssion .getM axIna ctive Inte rval( );

* a val ue a ssoci ated with the s essi on, d o not called on an * @aut hor C raig R. M cClan ahan import java. net. *; * no li mit. if ( maxIn activ eInte rval = max Inact iveI nterv al)

retu rn ( this. lastA ccess edTim e); * ge tAttr ibute Names () * sessi on.ex pire( );

*/ final c lass Stan dardS essio nCont ext i mple ments Http Sessi onCon text { * @aut hor J ames Dunc an Da vidso n [du ncan @eng. sun.c om] } }

} pub lic S trin g[] g etVal ueNam es() { * @aut hor J ason Hunt er [j ch@en g.sun .com ] }

* @aut hor J ames Todd [gon zo@en g.sun .com ]

Vect or r esult s = n ew Ve ctor( ); pri vate Vect or du mmy = new Vecto r(); */ /**

/** Enum erat ion a ttrs = get Attri bute Names (); * Set t he m aximu m num ber o f act ives Sess ions allow ed, o r -1 for /**

* Retur n th e Man ager withi n whi ch t his S essio n whil e (a ttrs. hasMo reEle ments ()) { /** public class Ser verSe ssion Manag er im plem ents Sessi onMan ager { * no li mit. * Sleep for the durat ion s pecif ied by th e ch eckIn terv al

is vali d. Stri ng at tr = (Stri ng) a ttrs .next Eleme nt(); * Retur n th e ses sion ident ifier s of all sessi ons d efine d * * prope rty.

*/ resu lts.a ddEle ment( attr) ; * withi n th is co ntext . pri vate Stri ngMan ager sm = * @para m ma x The new maxim um nu mber of s essio ns */

pub lic M anag er ge tMana ger() { } * Stri ngMa nager .getM anage r("or g.ap ache. tomca t.ses sion" ); */ pri vate void thre adSle ep() {

Stri ng n ames[ ] = n ew St ring[ resu lts.s ize() ]; * @depr ecat ed As of J ava S ervle t AP I 2.1 with no r eplac emen t. pri vate stat ic Se rverS essio nMana ger manag er; / / = n ew Se rver Sessi onMan ager( ); pub lic v oid setMa xActi veSes sions (int max) {

retu rn ( this. manag er); for (int i = 0; i Enu merat ion try {

name s[i] = (St ring) resu lts. eleme ntAt( i); * and will be r emove d in a fut ure versi on of the API. pro tecte d in t ina ctive Inter val = -1; this .max Activ eSess ions = max ; Thre ad.sl eep(c heckI nterv al * 1000 L);

} retu rn ( names ); */ } ca tch (Inte rrupt edExc eptio n e) {

pub lic E nume ratio n get Ids() { sta tic { } ;

} mana ger = new Serv erSes sionM anag er(); }

/** retu rn ( dummy .elem ents( )); }

* Set t he M anage r wit hin w hich this Sess ion i s // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- ---- Publ ic Me thods }

valid. /** } pub lic s tati c Ser verSe ssion Manag er g etMan ager( ) {

* * Inval idat es th is se ssion and unbi nds a ny ob jects boun d retu rn m anage r;

* @para m ma nager The new M anage r to it. } /** /**

*/ * /** * Const ruct and retur n a n ew se ssio n obj ect, based on t he d efaul t * Start the back groun d thr ead t hat will perio dical ly ch eck for

pub lic v oid setMa nager (Mana ger m anag er) { * @exce ptio n Ill egalS tateE xcept ion if th is me thod is * Retur n th e Ht tpSes sion as socia ted w ith t he pri vate Hash table sess ions = new Has htabl e(); * setti ngs speci fied by th is Ma nage r's p roper ties. The ses sion * sessi on t imeou ts.

called on * speci fied sess ion i denti fier. pri vate Reap er re aper; * id wi ll b e ass igned by t his m etho d, an d ava ilabl e via the getI d() */

this .man ager = man ager; * an i nval idate d ses sion * * metho d of the retur ned s essio n. If a new s essio n can not be cr eated pri vate void thre adSta rt() {

*/ * @para m id Sess ion i denti fier for which to l ook u p a s essi on pri vate Serv erSes sionM anage r() { * for a ny r eason , ret urn null .

} pub lic v oid inval idate () { * reap er = Reap er.ge tR * if ( thre ad != null )

* @depr ecat ed As of J ava S ervle t AP I 2.1 with no r eplac emen t. * @exce ptio n Ill egalS tateE xcept ion if a new s essio n can not be retu rn;

// C ause this sess ion t o exp ire * This met hod m ust r eturn null and will be r emove d in a * inst anti ated for a ny re ason

/** expi re() ; * futu re v ersio n of the A PI. */ thre adDo ne = false ;

* Retur n th e max imum time inter val, in s econd s, */ pub lic S essi on cr eateS essio n() { thre ad = new Threa d(thi s, th read Name) ;

between clie nt r eques ts } pub lic H ttpS essio n get Sessi on(St ring id) { thre ad.s etDae mon(t rue);

* befor e th e ser vlet conta iner will inva lidat e if ( (max Activ eSess ions >= 0) && thre ad.s tart( );

the ses sion. A negat ive retu rn ( null) ; (s essi ons.s ize() >= m axAct iveS essio ns))

* time indi cates that the sessi on s hould neve r /** thro w new Ille galSt ateEx cept ion }

time ou t. * Retur n t rue if t he c lient does not yet k now } (sm.g etStr ing(" stand ardM anage r.cre ateSe ssion .ise "));

* about t he

* @exce ptio n Ill egalS tateE xcept ion if th is * sessi on, or if the clien t cho oses not to jo in th e } retu rn ( super .crea teSes sion( )); /**

method is ca lled on session . Fo r * Stop the backg round thre ad th at i s per iodic ally check ing for

* an i nval idate d ses sion * examp le, if th e ser ver u sed o nly cooki e-bas ed se ssion s, } * sessi on t imeou ts.

*/ and the clie nt */

pub lic i nt g etMax Inact iveIn terva l() { * has d isab led t he us e of cooki es, then a ses sion would be pri vate void thre adSto p() {

new on each

retu rn ( this. maxIn activ eInte rval ); * reque st. if ( thre ad == null )

* retu rn;

} * @exce ptio n Ill egalS tateE xcept ion if th is me thod is

called on an thre adDo ne = true;

* inva lida ted s essio n thre ad.i nterr upt() ;

/** */ try {

* Set t he m aximu m tim e int erval , in seco nds, pub lic b oole an is New() { thre ad.jo in();

between clie nt r eques ts } ca tch (Inte rrupt edExc eptio n e) {

* befor e th e ser vlet conta iner will inva lidat e retu rn ( this. isNew ); ;

the ses sion. A negat ive }

* time indi cates that the sessi on s hould neve r }

time ou t. thre ad = null ;

*

* @para m in terva l The new maxim um i nterv al }

*/

pub lic v oid setMa xInac tiveI nterv al(i nt in terva l)

{ // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- - Ba ckgro und T hread



this .max Inact iveIn terva l = i nter val;

/**

} * The b ackg round thre ad th at ch ecks for sessi on ti meout s an d shu tdown .

*/

pub lic v oid run() {



// L oop until the termi natio n se mapho re is set

whil e (! threa dDone ) {

thre adSle ep();

proc essEx pires ();

}









6

}





}









CASCON '04

problems like…

session tracking is not modularized



HTTPRequest

SessionInterceptor

getCookies()

getRequestURI()(doc) requestMap(request)

getSession() beforeBody(req, resp)

getRequestedSessionId() ...

...





Session

HTTPResponse

getAttribute(name)

getRequest() setAttribute(name, val)

setContentType(contentType) invalidate()

getOutptutStream() ...

setSessionId(id)

...



Servlet

7

CASCON '04

the problem of crosscutting

concerns

• critical aspects of large systems don‟t fit in traditional

modules

– logging, error handling

– synchronization

– security

– power management

– memory management

– performance optimizations

• tangled code has a cost logging, security, optimizations

– difficult to understand

– difficult to change

– increases with size of system

– maintenance costs are huge

• good programmers work hard to get rid of tangled code

– the last 10% of the tangled code causes 90% of the

development and maintenance headaches

8

CASCON '04

the AOP idea

aspect-oriented programming





• crosscutting is inherent in complex systems

• crosscutting concerns

– have a clear purpose

– have a natural structure

• defined set of methods, module boundary crossings,

points of resource utilization, lines of dataflow…

• so, let‟s capture the structure of crosscutting

concerns explicitly...

– in a modular way

– with linguistic and tool support

• aspects are

– well-modularized crosscutting concerns

• Aspect-Oriented Software Development: AO

9 support throughout lifecycle

CASCON '04

this tutorial is about...



• using AOP and AspectJ to:

– improve the modularity of crosscutting concerns

• design modularity

• source code modularity

• development process

• aspects are two things:

– concerns that crosscut [design level]

– a programming construct [implementation level]

• enables crosscutting concerns

to be captured in modular units

• AspectJ is:

– an aspect-oriented extension to Java™ that supports

general-purpose aspect-oriented programming



10

CASCON '04

language support to…

App ca onSess on

ApplicationSession S andardSess on

StandardSession

/* public void inva lidat e() { package org. apac he.to mcat. sessi on; /**

* ==== ===== ==== ===== ===== ===== ===== ==== ===== ===== ===== ===== ==== ===== == serv erSe ssion .remo veApp licat ionS essio n(con text) ; /** * Bind an o bject to t his s essio n, u sing the s pecif ied n ame. If an ob ject

* * Retur n th e Ht tpSes sion fo r whi ch th is * of th e sa me na me is alre ady b ound to t his s essio n, th e ob ject is

* The Apach e So ftwar e Lic ense, Vers ion 1.1 // r emov e eve rythi ng in the sess ion import java. io.I OExce ption ; object * repla ced.

* import java. io.O bject Input Strea m; * is th e fa cade. *

* Copy right (c) 1999 The Apach e Sof twar e Fou ndati on. All r ight s Enum erat ion e num = valu es.ke ys() ; import java. io.O bject Outpu tStre am; */ * After thi s met hod e xecut es, a nd i f the obje ct im pleme nts

* rese rved. whil e (e num.h asMor eElem ents( )) { import java. io.S erial izabl e; pub lic H ttpS essio n get Sessi on() { * Htt pSess ionBi nding Liste ner, th e con taine r ca lls

* Stri ng na me = (Stri ng)en um.n extEl ement (); import java. util .Enum erati on; * val ueBou nd() on the objec t.

* Redi strib utio n and use in so urce and binar y for ms, w ith o r wi thout remo veVal ue(na me); import java. util .Hash table ; retu rn ( (Http Sessi on) t his); *

* modi ficat ion, are permi tted provi ded that the f ollow ing c ondi tions } import java. util .Vect or; * @para m na me Na me to whic h the obj ect i s bou nd, c annot be null

* are met: import javax .ser vlet. Servl etExc eptio n; } * @para m va lue O bject to b e bou nd, canno t be null

* vali d = false ; import javax .ser vlet. http. HttpS essio n; *

* 1. R edist ribu tions of s ource code mus t ret ain t he ab ove c opyr ight } import javax .ser vlet. http. HttpS essio nBin dingE vent; * @exce ptio n Ill egalS tateE xcept ion if th is me thod is ca lled on a n

* n otice , th is li st of cond ition s an d the foll owing disc laim er. import javax .ser vlet. http. HttpS essio nBin dingL isten er; // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- - * inva lida ted s essio n

* pub lic b oole an is New() { import javax .ser vlet. http. HttpS essio nCon text; Session Publ ic M ethod s *

* 2. R edist ribu tions in b inary form mus t rep roduc e the abov e co pyrig ht if ( ! va lid) { import org.a pach e.tom cat.c atali na.*; * @depr ecat ed As of V ersio n 2.2 , th is me thod is re place d by

* n otice , th is li st of cond ition s an d the foll owing disc laim er in Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.se ssio n.ise "); import org.a pach e.tom cat.u til.S tring Mana ger; * se tAttr ibute ()

* t he do cume ntati on an d/or other mat erial s pro vided with the /** */

* d istri buti on. thro w new Ille galSt ateEx cept ion(m sg); * Updat e th e acc essed time info rmat ion f or th is se ssion . pub lic v oid putVa lue(S tring name , Ob ject value ) {

* } /** This me thod

* 3. T he en d-us er do cumen tatio n inc lude d wit h the redi strib utio n, if * Stan dard impl ement ation of t he Ses sion * shoul d be call ed by the conte xt w hen a requ est c omes in setA ttri bute( name, valu e);

* a ny, m ust inclu de th e fol lowin g ac knowl egeme nt: if ( this Acces sTime == c reati onTi me) { interfa ce. This obje ct is for a p artic ular

* "Th is p roduc t inc ludes soft ware deve loped by t he retu rn tr ue; * seri aliza ble, so t hat i t can be s tore d in * sessi on, even if th e app licat ion does not r efere nce i t. }

* Ap ache Soft ware Found ation (ht tp:// www.a pache .org/ )." } el se { persist ent s tora ge or tran sferr ed */

* A ltern atel y, th is ac knowl egeme nt m ay ap pear in th e sof twar e retu rn fa lse; * to a diff eren t JVM for distr ibuta ble sessi on pub lic v oid acces s() {

itself, } support . /**

* i f and whe rever such thir d-par ty a cknow legem ents norma lly appea r. } * this .las tAcce ssedT ime = this .thi sAcce ssedT ime; * Remov e th e obj ect b ound with the speci fied name from this sess ion. If

* * I MPLEM ENTA TION NOTE: An i nsta nce o f thi s this .thi sAcce ssedT ime = Syst em.c urren tTime Milli s(); * the s essi on do es no t hav e an obje ct bo und w ith t his n ame, this meth od

* 4. T he na mes "The Jakar ta Pr oject ", " Tomca t", a nd "A pache Sof tware class r epres ents both the this .isN ew=fa lse; * does noth ing.

* F ounda tion " mus t not be u sed t o en dorse or p romot e pro duct s /** * inte rnal (Ses sion) and appli catio n le vel } *

derived * @depr ecat ed (HttpSe ssion ) vi ew of the sessi on. * After thi s met hod e xecut es, a nd i f the obje ct im pleme nts

* f rom t his softw are w ithou t pri or w ritte n per missi on. F or w ritte n */ * Howe ver, beca use t he cl ass i tself is not d eclar ed * Htt pSess ionBi nding Liste ner, th e con taine r ca lls

* p ermis sion , ple ase c ontac t apa che@ apach e.org . public, Java log ic ou tside /** * val ueUnb ound( ) o n th e obj ect.

* pub lic v oid putVa lue(S tring name , Ob ject value ) { * of t he org.a pache .tomc at.se ssio n * Perfo rm t he in terna l pro cessi ng r equir ed to inva lidat e *

* 5. P roduc ts d erive d fro m thi s sof twar e may not be ca lled "Apa che" setA ttri bute( name, valu e); package cann ot c ast a n this se ssion , * @para m na me Na me of the objec t to remo ve fr om th is se ssio n.

* n or ma y "A pache " app ear i n the ir n ames witho ut pr ior w ritt en } * Http Sessi on v iew o f thi s ins tance bac k to a * witho ut t rigge ring an ex cepti on i f the sess ion h as *

* p ermis sion of t he Ap ache Group . Session view . already expi red. * @exce ptio n Ill egalS tateE xcept ion if th is me thod is ca lled on a n

* pub lic v oid setAt tribu te(St ring name , Obj ect v alue) { * */ * inva lida ted s essio n

* THIS SOFT WARE IS P ROVID ED `` AS IS '' A ND AN Y EXP RESSE D OR IMPL IED if ( ! va lid) { * @aut hor C raig R. M cClan ahan pub lic v oid expir e() { */

* WARR ANTIE S, I NCLUD ING, BUT N OT LI MITE D TO, THE IMPLI ED WA RRAN TIES Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.se ssio n.ise "); * @ver sion $Rev ision : 1.2 $ $D ate: 2000 /05/1 5 pub lic v oid remov eAttr ibute (Stri ng n ame) {

* OF M ERCHA NTAB ILITY AND FITNE SS FO R A PARTI CULAR PURP OSE A RE 17:54:1 0 $ // R emov e thi s ses sion from our manag er's activ e

* DISC LAIME D. IN NO EVEN T SHA LL TH E AP ACHE SOFTW ARE F OUNDA TION OR thro w new Ille galSt ateEx cept ion(m sg); */ session s sync hron ized (attr ibute s) {

* ITS CONTR IBUT ORS B E LIA BLE F OR AN Y DI RECT, INDI RECT, INCI DENT AL, } if ( (man ager != nu ll) & & (ma nage r ins tance of Obje ct ob ject = att ribut es.g et(na me);

* SPEC IAL, EXEM PLARY , OR CONSE QUENT IAL DAMAG ES (I NCLUD ING, BUT NOT final c lass Stan dardS essio n Manager Base) ) if ( objec t == null)

* LIMI TED T O, P ROCUR EMENT OF S UBSTI TUTE GOOD S OR SERVI CES; LOSS OF if ( name == n ull) { imp lemen ts H ttpSe ssion , Ses sion { ((Ma nager Base) mana ger). remo ve(th is); retur n;

* USE, DATA , OR PROF ITS; OR BU SINES S IN TERRU PTION ) HOW EVER CAUS ED AN D Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.va lue. iae") ; attr ibute s.rem ove(n ame);

* ON A NY TH EORY OF L IABIL ITY, WHETH ER I N CON TRACT , STR ICT L IABI LITY, // U nbin d any obje cts a ssoci ated with this sess ion // S ystem .out. print ln( "Remo ving attri bute " + name );

* OR T ORT ( INCL UDING NEGL IGENC E OR OTHE RWISE ) ARI SING IN AN Y WA Y OUT thro w new Ille galAr gumen tExc eptio n(msg ); // ----- ---- ----- ----- ----- ----- ---- ----- ----- --- Vect or r esult s = n ew Ve ctor( ); if ( objec t ins tance of Ht tpSe ssion Bindi ngLis tener ) {

* OF T HE US E OF THIS SOFT WARE, EVEN IF ADVIS ED OF THE POSSI BILI TY OF } ------- ----- - Co nstru ctors Enum erat ion a ttrs = get Attri bute Names (); ((Htt pSess ionBi nding List ener) obje ct).v alueU nbou nd

* SUCH DAMA GE. whil e (a ttrs. hasMo reEle ments ()) { ( new H ttpSe ssion Bind ingEv ent(( HttpS essio n) t his, name) );

* ==== ===== ==== ===== ===== ===== ===== ==== ===== ===== ===== ===== ==== ===== == remo veVa lue(n ame); // remov e an y exi sting bind ing Stri ng at tr = (Stri ng) a ttrs .next Eleme nt(); }

* /** resu lts.a ddEle ment( attr) ; }

* This soft ware cons ists of vo lunta ry c ontri butio ns ma de by man y if ( valu e != null && va lue i nsta nceof Http Sessi onBin ding Liste ner) { * Const ruct a ne w Ses sion assoc iate d wit h the }

* indi vidua ls o n beh alf o f the Apac he S oftwa re Fo undat ion. For more Http Sessi onBin dingE vent e = specifi ed Ma nage r. Enum erat ion n ames = res ults. elem ents( ); }

* info rmati on o n the Apac he So ftwar e Fo undat ion, pleas e see new H ttpSe ssion Bindi ngEv ent(t his, name) ; * whil e (n ames. hasMo reEle ments ()) {

* . * @para m ma nager The manag er wi th w hich this Stri ng na me = (Stri ng) n ames .next Eleme nt();

* ((Ht tpSes sionB indin gList ener )valu e).va lueBo und(e ); Session is a ssoc iated remo veAtt ribut e(nam e); /**

* [Add ition al n otice s, if requ ired by p rior licen sing condi tion s] } */ } * Remov e th e obj ect b ound with the speci fied name from this sess ion. If

* pub lic S tand ardSe ssion (Mana ger m anag er) { * the s essi on do es no t hav e an obje ct bo und w ith t his n ame, this meth od

*/ valu es.p ut(na me, v alue) ; // M ark this sessi on as inva lid * does noth ing.

} supe r(); setV alid (fals e); *

this .man ager = man ager; * After thi s met hod e xecut es, a nd i f the obje ct im pleme nts

/** } * Htt pSess ionBi nding Liste ner, th e con taine r ca lls

package org. apac he.to mcat. sessi on; * @depr ecat ed } * val ueUnb ound( ) o n th e obj ect.

*/ *

import org.a pach e.tom cat.c ore.* ; pub lic O bjec t get Value (Stri ng na me) { /** * @para m na me Na me of the objec t to remo ve fr om th is se ssio n.

import org.a pach e.tom cat.u til.S tring Mana ger; retu rn g etAtt ribut e(nam e); // ----- ---- ----- ----- ----- ----- ---- ----- ----- --- * Relea se a ll ob ject refer ences , an d ini tiali ze in stanc e *

import java. io.* ; } ------- Inst ance Vari ables variabl es, i n * @exce ptio n Ill egalS tateE xcept ion if th is me thod is ca lled on a n

import java. net. *; * prepa rati on fo r reu se of this obj ect. * inva lida ted s essio n

import java. util .*; pub lic O bjec t get Attri bute( Strin g na me) { */ *

import javax .ser vlet. *; if ( ! va lid) { /** pub lic v oid recyc le() { * @depr ecat ed As of V ersio n 2.2 , th is me thod is re place d by

import javax .ser vlet. http. *; Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.se ssio n.ise "); * The c olle ction of u ser d ata a ttri butes * re moveA ttrib ute()

associa ted w ith this Sessi on. // R eset the insta nce v ariab les assoc iated with this */

/** thro w new Ille galSt ateEx cept ion(m sg); */ Session pub lic v oid remov eValu e(Str ing n ame) {

* Core impl emen tatio n of an ap plica tion leve l ses sion } pri vate Hash table attr ibute s = n ew H ashta ble() ; attr ibut es.cl ear() ;

* crea tion Time = 0L; remo veAt tribu te(na me);

* @aut hor J ames Dunc an Da vidso n [du ncan @eng. sun.c om] if ( name == n ull) { id = nul l;









Sess on n ercep or S andardManager

StandardManager S andardSess onManager

StandardSessionManager

* @aut hor J ason Hunt er [j ch@en g.sun .com ] Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.va lue. iae") ; /** last Acce ssedT ime = 0L; }

* @aut hor J ames Todd [gon zo@en g.sun .com ] * The t ime this sessi on wa s cre ated , in mana ger = nul l;

*/ thro w new Ille galAr gumen tExc eptio n(msg ); millise conds sin ce mi dnigh t, maxI nact iveIn terva l = - 1;

} * Janua ry 1 , 197 0 GMT . isNe w = true; /**

public class App licat ionSe ssion impl emen ts Ht tpSes sion { */ isVa lid = fal se; * Bind an o bject to t his s essio n, u sing the s pecif ied n ame. If an ob ject

retu rn v alues .get( name) ; pri vate long crea tionT ime = 0L; * of th e sa me na me is alre ady b ound to t his s essio n, th e ob ject is

pri vate Stri ngMan ager sm = } // T ell our M anage r tha t thi s Se ssion has been recyc led * repla ced.

Stri ngMa nager .getM anage r("or g.ap ache. tomca t.ses sion" ); if ( (man ager != nu ll) & & (ma nage r ins tance of *

pri vate Hash table valu es = new H asht able( ); /** /** Manager Base) ) * After thi s met hod e xecut es, a nd i f the obje ct im pleme nts

pri vate Stri ng id ; * @depr ecat ed * The s essi on id entif ier o f thi s Se ssion . ((Ma nager Base) mana ger). recy cle(t his); * Htt pSess ionBi nding Liste ner, th e con taine r ca lls

pri vate Serv erSes sion serve rSess ion; */ */ * val ueBou nd() on the objec t.

pri vate Cont ext c ontex t; pub lic S trin g[] g etVal ueNam es() { pri vate Stri ng id = nu ll; } *

pri vate long crea tionT ime = Syst em.c urren tTime Milli s();; Enum erat ion e = ge tAttr ibute Name s(); * @para m na me Na me to whic h the obj ect i s bou nd, c annot be null

pri vate long this Acces sTime = cr eati onTim e; Vect or n ames = new Vect or(); * @para m va lue O bject to b e bou nd, canno t be null package org. apac he.to mcat. sessi on; package org. apac he.to mcat. sessi on; // ---- ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- Pub lic

pri vate long last Acces sed = crea tion Time; /** // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- Sess ion * // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- - Li fecyc le Me thods Methods

pri vate int inact iveIn terva l = - 1; whil e (e .hasM oreEl ement s()) { * Descr ipti ve in forma tion descr ibin g thi s Package Meth ods * @exce ptio n Ill egalA rgume ntExc epti on if an a ttemp t is made to a dd a import java. io.I OExce ption ;

pri vate bool ean v alid = tru e; name s.add Eleme nt(e. nextE leme nt()) ; Session impl emen tatio n. * non- seri aliza ble o bject in a n en viron ment marke d dis trib utabl e. import java. util .Enum erati on; import java. io.I OExce ption ;

} */ * @exce ptio n Ill egalS tateE xcept ion if th is me thod is ca lled on a n import java. util .Hash table ; /**

import javax .ser vlet. http. Cooki e;

App licat ionS essio n(Str ing i d, Se rver Sessi on se rverS essio n, pri vate stat ic fi nal S tring info = /** * inva lida ted s essio n import java. util .Vect or; * Confi gure this comp onent , bas ed o n the spec ified conf igur ation

/**

Cont ext conte xt) { Stri ng[] valu eName s = n ew St ring [name s.siz e()]; "Standa rdSes sion /1.0" ; * Retur n th e is Valid f lag f or th is se ssion . */ import org.a pach e.tom cat.c atali na.*; * param eter s. T his m ethod shou ld b e cal led i mmedi ately aft er th e import javax .ser vlet. http. HttpS essio n;

this .ser verSe ssion = se rverS essi on; */ pub lic v oid setAt tribu te(St ring name , Obj ect v alue) { import javax .ser vlet. http. Cooki e; * compo nent inst ance is cr eated , an d bef ore start () * Mark the speci fied sessi on's last acce ssed time. Thi s sh ould be

import org.a pach e.tom cat.c atali na.*;

this .con text = con text; name s.co pyInt o(val ueNam es); boo lean isVa lid() { import javax .ser vlet. http. HttpS essio n; * is ca lled .

* calle d fo r eac h req uest by a Requ estIn terce ptor.

this .id = id; /** if ( (man ager != nu ll) & & man ager .getD istri butab le() && import org.a pach e.tom cat.u til.S tring Mana ger; * import org.a pach e.tom cat.c ore.C ontex t;

retu rn v alueN ames; * The l ast acces sed t ime f or th is S essio n. retu rn ( this. isVal id); !( valu e ins tance of Se riali zabl e)) import org.w 3c.d om.Na medNo deMap ; * @para m pa ramet ers C onfig urati on p arame ters for t his c ompo nent *

import org.a pach e.tom cat.c ore.R eques t;

this .ina ctive Inter val = cont ext. getSe ssion TimeO ut(); */ thro w new Ille galAr gumen tExc eptio n import org.w 3c.d om.No de; * ( FIXM E: Wh at ob ject type shou ld th is re ally be?)

* @para m se ssion The sessi on to be marke d

} pri vate long last Acces sedTi me = crea tionT ime; } (sm.g etStr ing(" stand ardS essio n.set Attri bute. iae" )); * import org.a pach e.tom cat.c ore.R espon se;

if ( this .inac tiveI nterv al != -1) { * @exce ptio n Ill egalS tateE xcept ion if th is co mpone nt ha s al ready been */

import org.a pach e.tom cat.c ore.S essio nMan ager;

this .inac tiveI nterv al *= 60; pub lic E nume ratio n get Attri buteN ames () { sync hron ized (attr ibute s) { /** * conf igur ed an d/or start ed

pub lic v oid acces sed(C ontex t ctx , Re quest req, Stri ng id ) {

} if ( ! va lid) { /** /** remo veAtt ribut e(nam e); * Stan dard impl ement ation of t he Man ager i nterf ace t hat provi des * @exce ptio n Lif ecycl eExce ption if this compo nent detec ts a fata l err or import org.a pach e.tom cat.u til.S essio nUti l;

} Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.se ssio n.ise "); * The M anag er wi th wh ich t his S essi on is * Set t he isNew fl ag f or th is se ssion . attr ibute s.put (name , val ue); * no s essio n pe rsist ence or di strib utab le ca pabil ities , but doe s sup port * in t he c onfig urati on pa ramet ers it wa s giv en Http Sess ion s essio n=fin dSess ion( ctx, id);

associa ted. * if ( value inst anceo f Htt pSes sionB indin gList ener) * an o ption al, confi gurab le, m aximu m nu mber of ac tive sessi ons allow ed. */

if( sess ion = = nul l) re turn;

Ser verSe ssio n get Serve rSess ion() { thro w new Ille galSt ateEx cept ion(m sg); */ * @para m is New T he ne w val ue fo r th e is New ((Htt pSess ionBi nding List ener) valu e).va lueBo und * pub lic v oid confi gure( Node param eter s)

retu rn s erver Sessi on; } pri vate Mana ger m anage r = n ull; flag ( new H ttpSe ssion Bind ingEv ent(( HttpS essio n) t his, name) ); * Life cycle con figur ation of t his c ompo nent assum es an XML node thro ws L ifecy cleEx cepti on { if ( sess ion i nstan ceof Sessi on)

/**

} */ } * in t he fo llow ing f ormat :

((Se ssion ) ses sion) .acce ss() ;

Hash tabl e val uesCl one = (Has htab le)va lues. clone (); voi d set New( boole an is New) { * // V alid ate a nd up date our c urre nt co mpone nt st ate * Spec ializ ed i mplem entat ion o f org .apa che.t omcat .core .Sess ionM anage r

/** /** } * <M anag er cl assNa me="o rg.ap ache .tomc at.se ssion .Stan dard Manag er" if ( conf igure d)

* that adap ts t o the new compo nent- base d Man ager imple menta tion .

* Calle d by cont ext w hen r eques t co mes i n so that acces ses and retu rn ( Enume ratio n)val uesCl one. keys( ); * The m axim um ti me in terva l, in sec onds, betw een this .isN ew = isNew ; * check Inter val=" 60" m axAc tiveS essio ns="- 1" thro w new Life cycle Excep tion

// c ache the HttpS essio n - a void anot her f ind

* inact ivit ies c an be deal t wit h ac cordi ngly. } client reque sts befor e * maxIn activ eInte rval= "-1" /> (sm.g etStr ing(" stand ardM anage r.alr eadyC onfig ured ")); *

*/ * the s ervl et co ntain er ma y inv alid ate t his } // ----- ---- ----- ----- ----- ----- ---- ----- ----- - Htt pSess ion Priva te Me thods * conf igur ed = true; req. setS essio n( se ssion );

* XXX - At pres ent, use o f St anda rdMan ager is hard code d,

session . A nega tive time * wher e you can adju st th e fol lowin g pa ramet ers, with defau lt v alues if ( para meter s == null)

}

voi d acc esse d() { /** * indic ates that the sessi on sh ould neve r tim e * in s quare bra ckets : retu rn; * and lifec ycle conf igura tion is no t su pport ed.

// s et l ast a ccess ed to this Acce ssTim e as it wi ll be lef t ove r * @depr ecat ed out. /** /** *

*

// f rom the p revio us ac cess */ */ * Set t he isVal id flag for this sessi on. * Read a se riali zed v ersio n of this sess ion o bject from the spec ified * ch eckI nterv al - T he in terv al (i n sec onds) betw een backg round // P arse and proce ss ou r con figu ratio n par amete rs

// XXX s houl d we throw exce ption or just retur n nul l ??

last Acce ssed = thi sAcce ssTim e; pri vate int maxIn activ eInte rval = -1 ; * * objec t in put s tream . * threa d ch ecks for e xpire d ses sion s. [ 60] if ( !("M anage r".eq uals( param eter s.get NodeN ame() ))) * I MPLEM ENTA TION NOTE: Once we commi t to the n ew

this Acce ssTim e = S ystem .curr entT imeMi llis( ); pub lic v oid remov eValu e(Str ing n ame) { * @para m is Valid The new v alue for the * * ma xAct iveSe ssion s - Th e ma ximum numb er of sess ions allo wed t o retu rn; Manager /Sess ion pub lic H ttpS essio n fin dSess ion( Cont ext c tx, S tring id ) {

remo veAt tribu te(na me); i sVali d flag * IM PLEM ENTAT ION N OTE: The refer ence to th e own ing Manag er * be ac tive at o nce, or -1 for no l imit. [-1 ] Name dNod eMap attri butes = pa rame ters. getAt tribu tes() ;

* para digm, I w ould sugge st mo ving the logic impl ement ed he re b ack i nto try {

vali date (); } /** */ * is no t re store d by this metho d, a nd mu st be set expli citl y. * ma xIna ctive Inter val - The defau lt ma ximum numb er o f sec onds of Node nod e = n ull;

} * Flag indi catin g whe ther this sess ion i s new or voi d set Vali d(boo lean isVal id) { * * inact ivit y bef ore w hich the s ervl et co ntain er is allo wed to ti me ou t * the core leve l. T he To mcat. Next "Man ager" inte rface acts mor e lik e a Sess ion s essio n = m anage r.fi ndSes sion( id);

pub lic v oid remov eAttr ibute (Stri ng n ame) { not. * @para m st ream The i nput strea m to read from * a ses sion , or -1 fo r no limit . T his v alue shoul d be over ridde n fro m node = a ttrib utes. getNa medIt em(" check Inter val") ;

* coll ectio n cl ass, and h as mi nimal kno wledg e of the d etail ed r eques t if(s essio n!=nu ll)

voi d val idat e() { if ( ! va lid) { */ this .isV alid = isV alid; * * the d efau lt se ssion time out s peci fied in th e web appl icat ion d eploy ment if ( node != n ull) {

// i f we have an i nacti ve in terv al, c heck to se e if we'v e exc eeded it Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.se ssio n.ise "); pri vate bool ean i sNew = tru e; } * @exce ptio n Cla ssNot Found Excep tion if a n unk nown class is speci fied * descr ipto r, if any. [-1 ] try { * proc essin g se manti cs of hand ling sess ions. retur n ses sion. getSe ssio n();

if ( inac tiveI nterv al != -1) { * @exce ptio n IOE xcept ion i f an inpu t/out put e rror occur s * setCh eckIn terva l(Int eger .pars eInt( node. getNo deVa lue() ));

* } ca tch (IOEx cepti on e) {

int thisI nterv al = thro w new Ille galSt ateEx cept ion(m sg); */ * } ca tch ( Throw able t) {

(int) (Syst em.cu rrent Time Milli s() - last Acces sed) / 10 00; } /** // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- - pri vate void read Objec t(Obj ectIn putS tream stre am) * @aut hor C raig R. M cClan ahan ; // XXX - Thr ow e xcept ion? * XXX - At pres ent, there is n o way (vi a the Sess ionMa nager int erfac e) }

* Flag indi catin g whe ther this sess ion i s val id HttpSes sion Prop ertie s thro ws C lassN otFou ndExc eptio n, I OExce ption { * @ver sion $Rev ision : 1.1 .1.1 $ $Da te: 2000/ 05/02 21:2 8:30 $ } for

retu rn ( null) ;

if ( thisI nterv al > inact iveI nterv al) { if ( name == n ull) { or not. */ }

* a Co ntext to tell the M anage r tha t we crea te wh at th e def ault sess ion

inval idate (); Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.va lue. iae") ; */ // D eser ializ e the scal ar in stan ce va riabl es (e xcept Man ager) }

} pri vate bool ean i sVali d = f alse; /** crea tion Time = ((L ong) strea m.re adObj ect() ).lon gValu e(); public final cla ss St andar dMana ger node = a ttrib utes. getNa medIt em(" maxAc tiveS essio ns"); * time out f or t his w eb ap plica tion (spe cifie d in the d eploy ment

} thro w new Ille galAr gumen tExc eptio n(msg ); * Retur n th e tim e whe n thi s ses sion was creat ed, i n id = (St ring) stre am.re adObj ect( ); ext ends Mana gerBa se if ( node != n ull) { descrip tor)

} } millise conds sin ce last Acce ssedT ime = ((Lo ng) s trea m.rea dObje ct()) .long Valu e(); imp lemen ts L ifecy cle, Runna ble { try { pub lic H ttpS essio n cre ateSe ssion (Con text ctx) {

* shou ld be .

/** * midni ght, Janu ary 1 , 197 0 GMT . maxI nact iveIn terva l = ( (Inte ger) stre am.re adObj ect() ).in tValu e(); setMa xActi veSes sions (Int eger. parse Int(n ode.g etNo deVal ue()) );

retu rn manag er.cr eateS essio n(). getSe ssion ();

// HTTP SESS ION I MPLEM ENTAT ION M ETHO DS Obje ct o = va lues. get(n ame); * The s trin g man ager for t his p acka ge. * isNe w = ((Boo lean) stre am.re adOb ject( )).bo olean Value (); } ca tch ( Throw able t) { *

*/ * @exce ptio n Ill egalS tateE xcept ion if th is me thod is isVa lid = ((B oolea n) st ream. read Objec t()). boole anVal ue() ; // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- Ins tance Vari ables ; // XXX - Thr ow e xcept ion? }

* @aut hor C raig R. M cClan ahan

pub lic S trin g get Id() { if ( o in stanc eof H ttpSe ssion Bind ingLi stene r) { pri vate Stri ngMan ager sm = called on an }

if ( vali d) { Http Sessi onBin dingE vent e = * inva lida ted s essio n // D eser ializ e the attr ibute cou nt an d att ribut e val ues } */

retu rn id ; new H ttpSe ssion Bindi ngEv ent(t his,n ame); StringM anage r.ge tMana ger(" org.a pache .tom cat.s essio n") */ int n = ((Int eger) stre am.re adOb ject( )).in tValu e(); /** /**

} el se { ; pub lic l ong getCr eatio nTime () { for (int i = 0; i * The d escr iptiv e inf ormat ion a bout this impl ement ation . // c onte xts, we ju st wa nt to rem ove t he se ssion s of ctx!

/**

thro w new Ille galSt ateEx cept ion(m sg); */ * repl acem ent. It w ill b e rem oved in a futu re ve rsion of * IM PLEM ENTAT ION N OTE: The ownin g Man ager will not be st ored */

// T he m anage r wil l sti ll ru n af ter t hat ( i.e. keep dat abase

} inac tive Inter val = inte rval; pri vate long this Acces sedTi me = crea tionT ime; the * in th e se riali zed r epres entat ion of th is Se ssion . Af ter calli ng pri vate stat ic fi nal S tring info = " Stand ardMa nager /1.0" ; /** * Creat e a new S essio nMana ger t hat adapt s to the c orres pond ing

} } * Java Ser vlet API. * rea dObje ct(), yo u mu st se t the asso ciate d Ma nager * Prepa re f or th e beg innin g of acti ve us e of the p ublic met hods of th is Manager // c onne ction open

*/ * expli citl y. * compo nent . Th is me thod shoul d be call ed af ter conf igure (),

* imple ment ation . if ( mana ger i nstan ceof Lifec ycle ) {

/** pub lic i nt g etMax Inact iveIn terva l() { pub lic H ttpS essio nCont ext g etSes sion Conte xt() { * /** * and b efor e any of t he pu blic meth ods o f the comp onent are util ized.

* if ( ! va lid) { * IM PLEM ENTAT ION N OTE: Any attri bute that is no t Se riali zable * The m axim um nu mber of ac tive Sess ions allow ed, o r -1 for no li mit. * */ try {

* @depr ecat ed Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.se ssio n.ise "); // ----- ---- ----- ----- ----- ----- ---- ----- ----- --- if ( sess ionCo ntext == n ull) * will be s ilent ly ig nored . If you do n ot wa nt an y suc h at tribu tes, */ * @exce ptio n Ill egalS tateE xcept ion if th is co mpone nt ha s no t yet been

pub lic S tand ardSe ssion Manag er() { ((Lif ecycl e) ma nager ).st op();

*/ ------- Sess ion Prope rties sess ionCo ntext = ne w Sta ndar dSess ionCo ntext (); * be su re t he d istri butab le prop erty of ou r as socia ted pro tecte d in t max Activ eSess ions = -1 ; * conf igur ed (i f req uired for this comp onent )

thro w new Ille galSt ateEx cept ion(m sg); retu rn ( sessi onCon text) ; * Manag er i s set to true. * @exce ptio n Ill egalS tateE xcept ion if th is co mpone nt ha s al ready been } ca tch ( Lifec ycleE xcept ion e) {

pub lic H ttpS essio nCont ext g etSes sion Conte xt() { } * * star ted

mana ger = new Stan dardM anage r(); throw new Illeg alSta teEx cepti on("" + e) ;

retu rn n ew Se ssion Conte xtImp l(); /** } * @para m st ream The o utput stre am t o wri te to /** * @exce ptio n Lif ecycl eExce ption if this compo nent detec ts a fata l err or

} retu rn i nacti veInt erval ; * Set t he c reati on ti me fo r thi s se ssion . Th is * * The s trin g man ager for t his p acka ge. * that pre vents this comp onent fro m bei ng us ed if ( mana ger i nstan ceof Lifec ycle ) { }

} method is ca lled by t he * @exce ptio n IOE xcept ion i f an inpu t/out put e rror occur s */ */

try { }

pub lic l ong getLa stAcc essed Time( ) { } * Manag er w hen a n exi sting Sess ion insta nce i s // ----- ---- ----- ----- ----- ----- ---- ----- ----- --- */ pri vate Stri ngMan ager sm = pub lic v oid start () th rows Lifec ycle Excep tion {

if ( vali d) { reused. HttpSes sion Publ ic Me thods pri vate void writ eObje ct(Ob jectO utpu tStre am st ream) thro ws I OExce ption { Stri ngMa nager .getM anage r("or g.ap ache. tomca t.ses sion" ); ((Lif ecycl e) ma nager ).co nfigu re(nu ll);

retu rn la stAcc essed ; * // V alid ate a nd up date our c urre nt co mpone nt st ate

((Lif ecycl e) ma nager ).st art() ; }

} el se { //----- ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- ---- ----- ---- * @para m ti me Th e new crea tion time // W rite the scala r ins tance var iable s (ex cept Manag er) if ( !con figur ed)

Stri ng ms g = s m.get Strin g("a pplic ation Sessi on.se ssio n.ise "); */ /** stre am.w riteO bject (new Long( crea tionT ime)) ; /** thro w new Life cycle Excep tion } ca tch ( Lifec ycleE xcept ion e) {

pub lic v oid setCr eatio nTime (long tim e) { * Retur n th e obj ect b ound with the speci fied name in th is stre am.w riteO bject (id); * Has t his compo nent been start ed y et? (sm.g etStr ing(" stand ardM anage r.not Confi gured "));

throw new Illeg alSta teEx cepti on("" + e) ; /**

thro w new Ille galSt ateEx cept ion(m sg); session , or stre am.w riteO bject (new Long( last Acces sedTi me)); */ if ( star ted)

} this .cre ation Time = tim e; * nul l i f no objec t is boun d wit h tha t nam e. stre am.w riteO bject (new Integ er(m axIna ctive Inter val)) ; pri vate bool ean s tarte d = f alse; thro w new Life cycle Excep tion } * Used by c ontex t to confi gure the sessi on ma nager 's in acti vity

} this .las tAcce ssedT ime = time ; * stre am.w riteO bject (new Boole an(i sNew) ); (sm.g etStr ing(" stand ardM anage r.alr eadyS tarte d")) ; timeout .

}

this .thi sAcce ssedT ime = time ; * @para m na me Na me of the attri bute to b e ret urned stre am.w riteO bject (new Boole an(i sVali d)); star ted = tru e;

*

* /**

} * @exce ptio n Ill egalS tateE xcept ion if th is me thod is // A ccum ulate the names of s eria lizab le at tribu tes * The b ackg round thre ad. // S tart the backg round reap er t hread * The S essi onMan ager may h ave s ome defau lt se ssion time out , the

}

called on an Vect or r esult s = n ew Ve ctor( ); */ thre adSt art() ;

* Conte xt o n the othe r han d has it' s tim eout set b y the dep loyme nt

* inva lida ted s essio n Enum erat ion a ttrs = get Attri bute Names (); pri vate Thre ad th read = nul l;

/** */ whil e (a ttrs. hasMo reEle ments ()) { } * descr ipto r (we b.xml ). Th is me thod lets the Conte xt co nfor gure the

* Retur n th e ses sion ident ifier for this pub lic O bjec t get Attri bute( Strin g na me) { Stri ng at tr = (Stri ng) a ttrs .next Eleme nt();

* sessi on m anage r acc ordin g to this valu e.

session . Obje ct va lue = attr ibute s.ge t(att r); /** // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- Ins tance

*/ retu rn ( attri butes .get( name) ); if ( value inst anceo f Ser iali zable ) * The b ackg round thre ad co mplet ion semap hore. /** Variabl es *

pub lic S trin g get Id() { resul ts.ad dElem ent(a ttr) ; */ * Grace full y ter minat e the acti ve u se of the publi c met hods of t his

* @para m mi nutes The sessi on in acti vity timeo ut in minu tes.

} } pri vate bool ean t hread Done = fal se; * compo nent . Th is me thod shoul d be the last one c alled on a giv en

retu rn ( this. id); * insta nce of th is co mpone nt. */

// S eria lize the a ttrib ute c ount and the attri bute valu es *

/** pub lic v oid setSe ssion TimeO ut(in t mi nutes ) {

} /** stre am.w riteO bject (new Integ er(r esult s.siz e())) ; /** * @exce ptio n Ill egalS tateE xcept ion if th is co mpone nt ha s no t bee n sta rted

* Retur n an Enu merat ion of Enum erat ion n ames = res ults. elem ents( ); * Name to r egist er fo r the back grou nd th read. * @exce ptio n Ill egalS tateE xcept ion if th is co mpone nt ha s al ready * The M anag er im pleme ntati on we are actu ally using . if(- 1 != minu tes) {

S tring o bject s whil e (n ames. hasMo reEle ments ()) { */ * been sto pped

*/ // T he ma nager work s wit h se conds ...

/** * conta inin g the name s of the o bjec ts bo und t o thi s Stri ng na me = (Stri ng) n ames .next Eleme nt(); pri vate Stri ng th readN ame = "Sta ndar dMana ger"; * @exce ptio n Lif ecycl eExce ption if this compo nent detec ts a fata l err or

* Set t he s essio n ide ntifi er fo r th is se ssion . session . stre am.wr iteOb ject( name) ; * that nee ds to be r eport ed pri vate Mana ger m anage r = n ull; mana ger.s etMax Inact iveIn terv al(mi nutes * 60 );

* * stre am.wr iteOb ject( attri bute s.get (name )); */

}

* @para m id The new s essio n ide ntif ier * @exce ptio n Ill egalS tateE xcept ion if th is me thod is } // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- ---- ---- Prope rties pub lic v oid stop( ) thr ows L ifecy cleE xcept ion {

*/ called on an }

pub lic v oid setId (Stri ng id ) { * inva lida ted s essio n // V alid ate a nd up date our c urre nt co mpone nt st ate

}

*/ } /** if ( !sta rted)

if ( (thi s.id != nu ll) & & (ma nage r != null) && pub lic E nume ratio n get Attri buteN ames () { * Retur n th e che ck in terva l (in sec onds) for this Manag er. thro w new Life cycle Excep tion

(m anag er in stanc eof M anage rBas e)) cro sscut inv alida te(St andar dSess ion s): s & (i nt ge tMaxI nact iveIn terva l() | */ (sm.g etStr ing(" stand ardM anage r.not Start ed")) ;

((Ma nager Base) mana ger). remo ve(th is); retu rn ( attri butes .keys ()); l ong g etCre atio nTime () | pub lic i nt g etChe ckInt erval () { star ted = fal se;

O bject getA ttri bute( Strin g) |

this .id = id; } E numer ation get Attri buteN ames( ) | retu rn ( this. check Inter val); // S top the b ackgr ound reape r th read

S tring [] ge tVal ueNam es() | thre adSt op();









ServerSess on

if ( (man ager != nu ll) & & (ma nage r ins tance of v oid i nvali date () | }

Manager Base) ) /** b oolea n isN ew() | // E xpir e all acti ve se ssion s

((Ma nager Base) mana ger). add( this) ; * Retur n th e obj ect b ound with the speci fied name in th is v oid r emove Attr ibute (Stri ng) | Sess ion sessi ons[] = fi ndSes sion s();

session , or v oid s etAtt ribu te(St ring, Obje ct)); /** for (int i = 0; i nul l i f no objec t is boun d wit h tha t nam e. * Set t he c heck inter val ( in se cond s) fo r thi s Man ager. Stan dardS essio n ses sion = (S tanda rdSes sion) sess ions [i];

* sta tic a dvic e(Sta ndard Sessi on s) : in valid ate(s ) { * if ( !sess ion.i sVali d())

* @para m na me Na me of the value to be re turne d befo re { * @para m ch eckIn terva l The new chec k int erval conti nue;

/** * if ( !s.is Valid ()) */ sess ion.e xpire ();

* Retur n de scrip tive infor matio n ab out t his * @exce ptio n Ill egalS tateE xcept ion if th is me thod is throw new Illeg alSta teEx cepti on pub lic v oid setCh eckIn terva l(int che ckInt erval ) { }

Session impl emen tatio n and called on an ( s.sm. getSt ring( "sta ndard Sessi on."









ServerSessionManager

ServerSess onManager

* the c orre spond ing v ersio n num ber, in t he * inva lida ted s essio n + th isJoi nPoin t.met hodNa me this .che ckInt erval = ch eckIn terv al; }

format * + ". ise") );

* * @depr ecat ed As of V ersio n 2.2 , th is me thod is re place d } }

& lt;de scri ption >/ <v ersio n> ;. by } // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- --- Priva te Me thods

*/ * ge tAttr ibute ()

pub lic S trin g get Info( ) { */ /**

pub lic O bjec t get Value (Stri ng na me) { * Retur n de scrip tive infor matio n ab out t his M anage r imp leme ntati on an d /**

retu rn ( this. info) ; * the c orre spond ing v ersio n num ber, in t he fo rmat * Inval idat e all sess ions that have expi red.

retu rn ( getAt tribu te(na me)); } * < ;desc ripti on> ;/< ;ver sion& gt; . */

} */ pri vate void proc essEx pires () {

} pub lic S trin g get Info( ) {

// ---- ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- ---- - Pri vate Class long tim eNow = Sys tem.c urren tTim eMill is();

/** retu rn ( this. info) ; Sess ion sessi ons[] = fi ndSes sion s();

* Retur n th e las t tim e the clie nt s ent a requ est /**

associa ted w ith this * Retur n th e set of n ames of ob ject s bou nd to this /** package org. apac he.to mcat. sessi on; } for (int i = 0; i Ht tpSes sion Conte xt Stan dardS essio n ses sion = (S tanda rdSes sion) sess ions [i];

midnigh t, Ja nuar y 1, 1970 * are n o su ch ob jects , a z ero-l engt h arr ay is retu rned. * inte rface , to conf orm t o the requ irem ent t hat s uch a n obj ect be re turne d import org.a pach e.tom cat.u til.* ; if ( !sess ion.i sVali d())

* GMT. Act ions that your appli cati on ta kes, * * when Ht tpSes sion. getSe ssion Cont ext() is call ed. import org.a pach e.tom cat.c ore.* ; /** conti nue;

such as gett ing or se tting * @exce ptio n Ill egalS tateE xcept ion if th is me thod is * import java. io.* ; * Retur n th e max imum numbe r of acti ve Se ssion s all owed, or -1 fo r int maxIn activ eInte rval = se ssion .getM axIna ctive Inte rval( );

* a val ue a ssoci ated with the s essi on, d o not called on an * @aut hor C raig R. M cClan ahan import java. net. *; * no li mit. if ( maxIn activ eInte rval = max Inact iveI nterv al)

retu rn ( this. lastA ccess edTim e); * ge tAttr ibute Names () * sessi on.ex pire( );

*/ final c lass Stan dardS essio nCont ext i mple ments Http Sessi onCon text { * @aut hor J ames Dunc an Da vidso n [du ncan @eng. sun.c om] } }

} pub lic S trin g[] g etVal ueNam es() { * @aut hor J ason Hunt er [j ch@en g.sun .com ] }

* @aut hor J ames Todd [gon zo@en g.sun .com ]

Vect or r esult s = n ew Ve ctor( ); pri vate Vect or du mmy = new Vecto r(); */ /**

/** Enum erat ion a ttrs = get Attri bute Names (); * Set t he m aximu m num ber o f act ives Sess ions allow ed, o r -1 for /**

* Retur n th e Man ager withi n whi ch t his S essio n whil e (a ttrs. hasMo reEle ments ()) { /** public class Ser verSe ssion Manag er im plem ents Sessi onMan ager { * no li mit. * Sleep for the durat ion s pecif ied by th e ch eckIn terv al

is vali d. Stri ng at tr = (Stri ng) a ttrs .next Eleme nt(); * Retur n th e ses sion ident ifier s of all sessi ons d efine d * * prope rty.

*/ resu lts.a ddEle ment( attr) ; * withi n th is co ntext . pri vate Stri ngMan ager sm = * @para m ma x The new maxim um nu mber of s essio ns */

pub lic M anag er ge tMana ger() { } * Stri ngMa nager .getM anage r("or g.ap ache. tomca t.ses sion" ); */ pri vate void thre adSle ep() {

Stri ng n ames[ ] = n ew St ring[ resu lts.s ize() ]; * @depr ecat ed As of J ava S ervle t AP I 2.1 with no r eplac emen t. pri vate stat ic Se rverS essio nMana ger manag er; / / = n ew Se rver Sessi onMan ager( ); pub lic v oid setMa xActi veSes sions (int max) {

retu rn ( this. manag er); for (int i = 0; i Enu merat ion try {

name s[i] = (St ring) resu lts. eleme ntAt( i); * and will be r emove d in a fut ure versi on of the API. pro tecte d in t ina ctive Inter val = -1; this .max Activ eSess ions = max ; Thre ad.sl eep(c heckI nterv al * 1000 L);

} retu rn ( names ); */ } ca tch (Inte rrupt edExc eptio n e) {

pub lic E nume ratio n get Ids() { sta tic { } ;

} mana ger = new Serv erSes sionM anag er(); }

/** retu rn ( dummy .elem ents( )); }

* Set t he M anage r wit hin w hich this Sess ion i s // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- ---- Publ ic Me thods }

valid. /** } pub lic s tati c Ser verSe ssion Manag er g etMan ager( ) {

* * Inval idat es th is se ssion and unbi nds a ny ob jects boun d retu rn m anage r;

* @para m ma nager The new M anage r to it. } /** /**

*/ * /** * Const ruct and retur n a n ew se ssio n obj ect, based on t he d efaul t * Start the back groun d thr ead t hat will perio dical ly ch eck for

pub lic v oid setMa nager (Mana ger m anag er) { * @exce ptio n Ill egalS tateE xcept ion if th is me thod is * Retur n th e Ht tpSes sion as socia ted w ith t he pri vate Hash table sess ions = new Has htabl e(); * setti ngs speci fied by th is Ma nage r's p roper ties. The ses sion * sessi on t imeou ts.

called on * speci fied sess ion i denti fier. pri vate Reap er re aper; * id wi ll b e ass igned by t his m etho d, an d ava ilabl e via the getI d() */

this .man ager = man ager; * an i nval idate d ses sion * * metho d of the retur ned s essio n. If a new s essio n can not be cr eated pri vate void thre adSta rt() {

*/ * @para m id Sess ion i denti fier for which to l ook u p a s essi on pri vate Serv erSes sionM anage r() { * for a ny r eason , ret urn null .

} pub lic v oid inval idate () { * reap er = Reap er.ge tR * if ( thre ad != null )

* @depr ecat ed As of J ava S ervle t AP I 2.1 with no r eplac emen t. * @exce ptio n Ill egalS tateE xcept ion if a new s essio n can not be retu rn;

// C ause this sess ion t o exp ire * This met hod m ust r eturn null and will be r emove d in a * inst anti ated for a ny re ason

/** expi re() ; * futu re v ersio n of the A PI. */ thre adDo ne = false ;

* Retur n th e max imum time inter val, in s econd s, */ pub lic S essi on cr eateS essio n() { thre ad = new Threa d(thi s, th read Name) ;

between clie nt r eques ts } pub lic H ttpS essio n get Sessi on(St ring id) { thre ad.s etDae mon(t rue);

* befor e th e ser vlet conta iner will inva lidat e if ( (max Activ eSess ions >= 0) && thre ad.s tart( );

the ses sion. A negat ive retu rn ( null) ; (s essi ons.s ize() >= m axAct iveS essio ns))

* time indi cates that the sessi on s hould neve r /** thro w new Ille galSt ateEx cept ion }

time ou t. * Retur n t rue if t he c lient does not yet k now } (sm.g etStr ing(" stand ardM anage r.cre ateSe ssion .ise "));

* about t he

* @exce ptio n Ill egalS tateE xcept ion if th is * sessi on, or if the clien t cho oses not to jo in th e } retu rn ( super .crea teSes sion( )); /**

method is ca lled on session . Fo r * Stop the backg round thre ad th at i s per iodic ally check ing for

* an i nval idate d ses sion * examp le, if th e ser ver u sed o nly cooki e-bas ed se ssion s, } * sessi on t imeou ts.

*/ and the clie nt */

pub lic i nt g etMax Inact iveIn terva l() { * has d isab led t he us e of cooki es, then a ses sion would be pri vate void thre adSto p() {

new on each

retu rn ( this. maxIn activ eInte rval ); * reque st. if ( thre ad == null )

* retu rn;

} * @exce ptio n Ill egalS tateE xcept ion if th is me thod is

called on an thre adDo ne = true;

* inva lida ted s essio n thre ad.i nterr upt() ;

/** */ try {

* Set t he m aximu m tim e int erval , in seco nds, pub lic b oole an is New() { thre ad.jo in();

between clie nt r eques ts } ca tch (Inte rrupt edExc eptio n e) {

* befor e th e ser vlet conta iner will inva lidat e retu rn ( this. isNew ); ;

the ses sion. A negat ive }

* time indi cates that the sessi on s hould neve r }

time ou t. thre ad = null ;

*

* @para m in terva l The new maxim um i nterv al }

*/

pub lic v oid setMa xInac tiveI nterv al(i nt in terva l)

{ // ----- ---- ----- ----- ----- ----- ---- ----- ----- ----- ----- - Ba ckgro und T hread



this .max Inact iveIn terva l = i nter val;

/**

} * The b ackg round thre ad th at ch ecks for sessi on ti meout s an d shu tdown .

*/

pub lic v oid run() {



// L oop until the termi natio n se mapho re is set

whil e (! threa dDone ) {

thre adSle ep();

proc essEx pires ();

}









11

}





}









CASCON '04

AspectJ™ is…



• a small and well-integrated extension to Java™

– outputs .class files compatible with any JVM

– all Java programs are AspectJ programs

• a general-purpose AO language

– just as Java is a general-purpose OO language

• includes IDE support

– emacs, JBuilder, Forte 4J, Eclipse

• freely available implementation

– compiler is Open Source

• active user community

– aspectj-users@eclipse.org



12

CASCON '04

AspectJ applied to a large

middleware system

• java code base with 10,000 files and 500 developers

• AspectJ captured logging, error handling, and profiling policies

– Packaged as extension to Java language

– Compatible with existing code base and platform

existing policy implementations policies implemented with AspectJ



• affect every file • one reusable crosscutting module

– 5-30 page policy documents – policy captured explicitly

– applied by developers – applies policy uniformly for all time

• affect every developer • written by central team

– must understand policy document – no burden on other 492 developers

• repeat for new code assets • automatically applied to new code

• awkward to support variants • easy plug and unplug

– complicates product line – simplifies product line issues

• don‟t even think about • changes to policy happen in one

changing the policy place







13

CASCON '04

looking ahead





problem structure

examples:

crosscutting in the design, and

how to use AspectJ to capture that



AspectJ language

language mechanisms:

crosscutting in the code

mechanisms AspectJ provides





14

CASCON '04

Part II





tutorial

language mechanisms



• goal: present basic mechanisms

– using one simple example

• emphasis on what the mechanisms do

• small scale motivation

• later

– environment, tools

– larger examples, design and SE issues









16

CASCON '04

basic mechanisms

• 1 overlay onto Java

– dynamic join points

• “points in the execution” of Java programs

• 4 small additions to Java

– pointcuts

• pick out join points and values at those points

– primitive, user-defined pointcuts

– advice

• additional action to take at join points in a pointcut

– inter-type declarations (aka “open classes”)

– aspect

• a modular unit of crosscutting behavior

– comprised of advice, inter-type, pointcut,

field, constructor, and method declarations



17

CASCON '04

a simple figure editor



factory methods

Display





Figure * FigureElement



makePoint(..) moveBy(int, int)

makeLine(..)









Point 2 Line



getX() getP1()

getY() getP2()

setX(int) setP1(Point) operations that

setY(int) setP2(Point) move elements

18

moveBy(int, int) moveBy(int, int)

CASCON '04

a simple figure editor

class Line implements FigureElement{

private Point p1, p2;

Point getP1() { return p1; }

Point getP2() { return p2; }

void setP1(Point p1) { this.p1 = p1; }

void setP2(Point p2) { this.p2 = p2; }

void moveBy(int dx, int dy) { ... }

}



class Point implements FigureElement {

private int x = 0, y = 0;

int getX() { return x; }

int getY() { return y; }

void setX(int x) { this.x = x; }

void setY(int y) { this.y = y; }

void moveBy(int dx, int dy) { ... }

}



19

CASCON '04

display updating



• collection of figure elements

– that move periodically

– must refresh the display as needed

– complex collection

– asynchronous events



• other examples

– session liveness

– value caching

we will initially assume

just a single display





20

CASCON '04

join points

key points in dynamic call graph



imagine l.moveBy(2, 2)





a Line



dispatch









a Point



a method execution a method call dispatch

returning or

returning or throwing

throwing







a method execution

returning or throwing





21

CASCON '04

join point terminology



a Line



dispatch





method

execution method call

join points join points



• several kinds of join points

– method & constructor call

– method & constructor execution

– field get & set

– exception handler execution

– static & dynamic initialization

22

CASCON '04

join point terminology

key points in dynamic call graph



imagine l.moveBy(2, 2) a Point





a Line









a Point









all join points on this slide are

within the control flow of

this join point







23

CASCON '04

primitive pointcuts

“a means of identifying join points”





a pointcut is a kind of predicate on join points that:

– can match or not match any given join point and

– optionally, can pull out some of the values at that join point









call(void Line.setP1(Point))









matches if the join point is a method call with this signature









24

CASCON '04

pointcut composition



pointcuts compose like predicates, using &&, || and !







a “void Line.setP1(Point)” call

or

call(void Line.setP1(Point)) ||

call(void Line.setP2(Point));





a “void Line.setP2(Point)” call

whenever a Line receives a

“void setP1(Point)” or “void setP2(Point)” method call



25

CASCON '04

user-defined pointcuts

defined using the pointcut construct





user-defined (aka named) pointcuts

– can be used in the same way as primitive pointcuts



name parameters



pointcut move():

call(void Line.setP1(Point)) ||

call(void Line.setP2(Point));





more on parameters

and how pointcut can

expose values at join

points in a few slides





26

CASCON '04

pointcuts







user-defined pointcut



pointcut move():

call(void Line.setP1(Point)) ||

call(void Line.setP2(Point));





primitive pointcut, can also be:

- call, execution - this, target

- get, set - within, withincode

- handler - cflow, cflowbelow

- initialization, staticinitialization



27

CASCON '04

after advice action to take after

computation under join points



after advice runs

“on the way back out”

a Line









pointcut move():

call(void Line.setP1(Point)) ||

call(void Line.setP2(Point));



after() returning: move() {



}









28

CASCON '04

a simple aspect

DisplayUpdating v1



an aspect defines a special class

that can crosscut other classes





aspect DisplayUpdating {



pointcut move():

call(void Line.setP1(Point)) ||

call(void Line.setP2(Point));



after() returning: move() {

Display.update();

}

}





box means complete running code

29

CASCON '04

without AspectJ

DisplayUpdating v1



class Line {

private Point p1, p2;



Point getP1() { return p1; }

Point getP2() { return p2; }



void setP1(Point p1) {

this.p1 = p1;

Display.update();

}

void setP2(Point p2) {

this.p2 = p2;

Display.update();

}

}







• what you would expect

– update calls are tangled through the code

– “what is going on” is less explicit



30

CASCON '04

pointcuts

can cut across multiple classes









pointcut move():

call(void Line.setP1(Point)) ||

call(void Line.setP2(Point)) ||

call(void Point.setX(int)) ||

call(void Point.setY(int));









31

CASCON '04

pointcuts

can use interface signatures









pointcut move():

call(void FigureElement.moveBy(int, int)) ||

call(void Line.setP1(Point)) ||

call(void Line.setP2(Point)) ||

call(void Point.setX(int)) ||

call(void Point.setY(int));









32

CASCON '04

a multi-class aspect

DisplayUpdating v2









aspect DisplayUpdating {



pointcut move():

call(void FigureElement.moveBy(int, int)) ||

call(void Line.setP1(Point)) ||

call(void Line.setP2(Point)) ||

call(void Point.setX(int)) ||

call(void Point.setY(int));



after() returning: move() {

Display.update();

}

}

33

CASCON '04

using values at join points

demonstrate first, explain in detail afterwards





• pointcut can explicitly expose certain values

• advice can use those values



parameter

mechanism

pointcut move(FigureElement figElt): being used

target(figElt) &&

(call(void FigureElement.moveBy(int, int)) ||

call(void Line.setP1(Point)) ||

call(void Line.setP2(Point)) ||

call(void Point.setX(int)) ||

call(void Point.setY(int)));



after(FigureElement fe) returning: move(fe) {



}

34

CASCON '04

explaining parameters…

of user-defined pointcut designator



• variable is bound by user-defined pointcut declaration

– pointcut supplies value for variable

– value is available to all users of user-defined pointcut





pointcut parameters

pointcut move(Line l):

target(l) &&

(call(void Line.setP1(Point)) ||

call(void Line.setP2(Point)));



typed variable in place of type name



after(Line line) returning: move(line) {



}

35

CASCON '04

explaining parameters…

of advice



• variable is bound by advice declaration

– pointcut supplies value for variable

– value is available in advice body







pointcut move(Line l):

target(l) &&

(call(void Line.setP1(Point)) ||

call(void Line.setP2(Point)));

typed variable in place

advice parameters

of type name



after(Line line) returning: move(line) {



}

36

CASCON '04

explaining parameters…



• value is „pulled‟

– right to left across „:‟ left side : right side

– from pointcuts to user-defined pointcuts

– from pointcuts to advice, and then advice body





pointcut move(Line l):

target(l) &&

(call(void Line.setP1(Point)) ||

call(void Line.setP2(Point)));









after(Line line) returning: move(line) {



}

37

CASCON '04

target

primitive pointcut designator



target( TypeName | FormalReference )



does two things:

- exposes target

- predicate on join points - any join point at which target object

is an instance of type name (a dynamic test)



target(Point)

target(Line)

target(FigureElement)



“any join point” means it matches join points of all kinds

• method call join points

• method & constructor execution join points

• field get & set join points

• dynamic initialization join points

38

CASCON '04

idiom for…

getting target object in a polymorphic pointcut





target( SupertypeName ) &&



• does not further restrict the join points

• does pick up the target object

pointcut move(FigureElement figElt):

target(figElt) &&

(call(void Line.setP1(Point)) ||

call(void Line.setP2(Point)) ||

call(void Point.setX(int)) ||

call(void Point.setY(int)));



after(FigureElement fe) returning: move(fe) {



}

39

CASCON '04

pointcuts

can expose values at join points







pointcut move(FigureElement figElt):

target(figElt) &&

(call(void FigureElement.moveBy(int, int)) ||

call(void Line.setP1(Point)) ||

call(void Line.setP2(Point)) ||

call(void Point.setX(int)) ||

call(void Point.setY(int)));









40

CASCON '04

context & multiple classes

DisplayUpdating v3



aspect DisplayUpdating {



pointcut move(FigureElement figElt):

target(figElt) &&

(call(void FigureElement.moveBy(int, int)) ||

call(void Line.setP1(Point)) ||

call(void Line.setP2(Point)) ||

call(void Point.setX(int)) ||

call(void Point.setY(int)));



after(FigureElement fe) returning: move(fe) {

Display.update(fe);

}

}









41

CASCON '04

without AspectJ

class Line {

private Point p1, p2;



Point getP1() { return p1; }

Point getP2() { return p2; }



void setP1(Point p1) {

this.p1 = p1;



}

void setP2(Point p2) {

this.p2 = p2;



}

void moveBy(int dx, int dy) { … }

}





class Point {

private int x = 0, y = 0;



int getX() { return x; }

int getY() { return y; }



void setX(int x) {

this.x = x;



}

void setY(int y) {

this.y = y;



}

void moveBy(int dx, int dy) { … }

}

42

CASCON '04

without AspectJ

DisplayUpdating v1

class Line {

private Point p1, p2;



Point getP1() { return p1; }

Point getP2() { return p2; }



void setP1(Point p1) {

this.p1 = p1;

Display.update();

}

void setP2(Point p2) {

this.p2 = p2;

Display.update();

}

void moveBy(int dx, int dy) { … }

}





class Point {

private int x = 0, y = 0;



int getX() { return x; }

int getY() { return y; }



void setX(int x) {

this.x = x;



}

void setY(int y) {

this.y = y;



}

void moveBy(int dx, int dy) { … }

}

43

CASCON '04

without AspectJ

DisplayUpdating v2

class Line {

private Point p1, p2;



Point getP1() { return p1; }

Point getP2() { return p2; }



void setP1(Point p1) {

this.p1 = p1;

Display.update();

}

void setP2(Point p2) {

this.p2 = p2;

Display.update();

}

void moveBy(int dx, int dy) { … }

}





class Point {

private int x = 0, y = 0;



int getX() { return x; }

int getY() { return y; }



void setX(int x) {

this.x = x;

Display.update();

}

void setY(int y) {

this.y = y;

Display.update();

}

void moveBy(int dx, int dy) { … }

}

44

CASCON '04

without AspectJ

DisplayUpdating v3

class Line {

private Point p1, p2;



Point getP1() { return p1; }

Point getP2() { return p2; }



void setP1(Point p1) {

this.p1 = p1;

Display.update(this);

}

void setP2(Point p2) {

this.p2 = p2;

Display.update(this);

}

void moveBy(int dx, int dy) { … }

}





class Point {

private int x = 0, y = 0;



int getX() { return x; }

int getY() { return y; }



void setX(int x) {

• no locus of “display updating”

this.x = x;

Display.update(this);

– evolution is cumbersome

}

void setY(int y) { – changes in all classes

– have to track & change all callers

this.y = y;

Display.update(this);

}

void moveBy(int dx, int dy) { … }

}

45

CASCON '04

with AspectJ

class Line {

private Point p1, p2;



Point getP1() { return p1; }

Point getP2() { return p2; }



void setP1(Point p1) {

this.p1 = p1;



}

void setP2(Point p2) {

this.p2 = p2;



}

void moveBy(int dx, int dy) { … }

}





class Point {

private int x = 0, y = 0;



int getX() { return x; }

int getY() { return y; }



void setX(int x) {

this.x = x;



}

void setY(int y) {

this.y = y;



}

void moveBy(int dx, int dy) { … }

}

46

CASCON '04

with AspectJ

DisplayUpdating v1

class Line {

private Point p1, p2;

aspect DisplayUpdating {

Point getP1() { return p1; }

Point getP2() { return p2; }

pointcut move():

call(void Line.setP1(Point)) ||

void setP1(Point p1) {

call(void Line.setP2(Point));

this.p1 = p1;

after() returning: move() {

}

Display.update();

void setP2(Point p2) {

}

this.p2 = p2;

}

}

void moveBy(int dx, int dy) { … }

}





class Point {

private int x = 0, y = 0;



int getX() { return x; }

int getY() { return y; }



void setX(int x) {

this.x = x;



}

void setY(int y) {

this.y = y;



}

void moveBy(int dx, int dy) { … }

}

47

CASCON '04

with AspectJ

DisplayUpdating v2

class Line {

private Point p1, p2;

aspect DisplayUpdating {

Point getP1() { return p1; }

Point getP2() { return p2; }

pointcut move():

call(void FigureElement.moveBy(int, int) ||

void setP1(Point p1) {

call(void Line.setP1(Point)) ||

this.p1 = p1;

call(void Line.setP2(Point)) ||

call(void Point.setX(int)) ||

}

call(void Point.setY(int));

void setP2(Point p2) {

this.p2 = p2;

after() returning: move() {

Display.update();

}

}

void moveBy(int dx, int dy) { … }

}

}





class Point {

private int x = 0, y = 0;



int getX() { return x; }

int getY() { return y; }



void setX(int x) {

this.x = x;



}

void setY(int y) {

this.y = y;



}

void moveBy(int dx, int dy) { … }

}

48

CASCON '04

with AspectJ

DisplayUpdating v3

class Line {

private Point p1, p2;

aspect DisplayUpdating {

Point getP1() { return p1; }

Point getP2() { return p2; }

pointcut move(FigureElement figElt):

target(figElt) &&

void setP1(Point p1) {

(call(void FigureElement.moveBy(int, int) ||

this.p1 = p1;

call(void Line.setP1(Point)) ||

call(void Line.setP2(Point)) ||

}

call(void Point.setX(int)) ||

void setP2(Point p2) {

call(void Point.setY(int)));

this.p2 = p2;



}

after(FigureElement fe) returning: move(fe) {

void moveBy(int dx, int dy) { … }

Display.update(fe);

}

}

}

class Point {

private int x = 0, y = 0;



int getX() { return x; }

int getY() { return y; }



void setX(int x) {

• clear display updating module

this.x = x;

– all changes in single aspect

}

void setY(int y) {

this.y = y;

– evolution is modular

}

void moveBy(int dx, int dy) { … }

}

49

CASCON '04

aspects crosscut classes



aspect modularity cuts across

Display class modularity



Figure * FigureElement



makePoint(..) moveBy(int, int)

makeLine(..)









Point 2 Line



getX() getP1()

getY() getP2()

setX(int) setP1(Point)

setY(int) setP2(Point) DisplayUpdating

50

moveBy(int, int) moveBy(int, int)

CASCON '04

advice is

additional action to take at join points





• before before proceeding at join point





• after returning a value at join point

• after throwing a throwable at join point

• after returning at join point either way





• around on arrival at join point gets explicit

control over when&if program proceeds









51

CASCON '04

contract checking

simple example of before/after/around





• pre-conditions

– check whether parameter is valid

• post-conditions

– check whether values were set

• condition enforcement

– force parameters to be valid









52

CASCON '04

pre-condition

using before advice



aspect PointBoundsPreCondition {



before(int newX):

call(void Point.setX(int)) && args(newX) {

assert newX >= MIN_X; what follows the „:‟ is

assert newX = MIN_Y;

assert newY ;



after(FigureElement fe): move(fe) {

fe.display.update(fe);

}

}







74

CASCON '04

field/getter/setter idiom

private with respect to

aspect DisplayUpdating {

enclosing aspect declaration

private Display FigureElement.display;



public static void setDisplay(FigureElement fe, Display d) {

fe.display = d;

}

the display field

pointcut move(FigureElement figElt):



; is a field in objects of type FigureElement, but

– belongs to DisplayUpdating aspect

– DisplayUpdating {

after(FigureElement fe): move(fe) should provide getter/setter

fe.display.update(fe); setup code)

(called by

}

}









75

CASCON '04

one-to-many

DisplayUpdating v6



aspect DisplayUpdating {



private List FigureElement.displays = new LinkedList();



public static void addDisplay(FigureElement fe, Display d) {

fe.displays.add(d);

}

public static void removeDisplay(FigureElement fe, Display d) {

fe.displays.remove(d);

}



pointcut move(FigureElement figElt):

;



after(FigureElement fe): move(fe) {

Iterator iter = fe.displays.iterator();

...

}

}

76

CASCON '04

inheritance & specialization



• pointcuts can have additional advice

– aspect with

• concrete pointcut

• perhaps no advice on the pointcut

– in figure editor

• move() can have advice from multiple aspects

– module can expose certain well-defined pointcuts



• abstract pointcuts can be specialized

– aspect with

• abstract pointcut

• concrete advice on the abstract pointcut





77

CASCON '04

role types and reusable aspects



abstract aspect Observing {

protected interface Subject { }

protected interface Observer { }



private List Subject.observers = new ArrayList();

public void addObserver(Subject s, Observer o) { ... }

public void removeObserver(Subject s, Observer o) { ... }

public static List getObservers(Subject s) { ... }



abstract pointcut changes(Subject s);



after(Subject s): changes(s) {

Iterator iter = getObservers(s).iterator();

while ( iter.hasNext() ) {

notifyObserver(s, ((Observer)iter.next()));

}

}

abstract void notifyObserver(Subject s, Observer o);

}

78

CASCON '04

this is the concrete reuse

DisplayUpdating v7



aspect DisplayUpdating extends Observing {



declare parents: FigureElement implements Subject;

declare parents: Display implements Observer;



pointcut changes(Subject s):

target(s) &&

(call(void FigureElement.moveBy(int, int)) ||

call(void Line.setP1(Point)) ||

call(void Line.setP2(Point)) ||

call(void Point.setX(int)) ||

call(void Point.setY(int)));



void notifyObserver(Subject s, Observer o) {

((Display)o).update(s);

}

}



79

CASCON '04

advice precedence

• what happens if two pieces of advice

apply to the same join point?

aspect Security {

before(): call(public *(..)) {

if (!Policy.isAllwed(tjp))

throw new SecurityExn();

}



}

please read as

thisJoinPoint aspect Logging {

before(): logged() {

System.err.println(

"Entering " + tjp);

}

pointcut logged():

call(void troublesomeMethod());

}

80

CASCON '04

advice precedence

• order is undefined, unless...

– in the same aspect,

– in subaspect, or aspect Security {

before(): call(public *(..)) {

– using declare if (!Policy.isAllwed(tjp))

precedence... throw new SecurityExn();

}

declare precedence: Security, *;

}



aspect Logging {

before(): logged() {

System.err.println(

"Entering " + tjp);

}

pointcut logged():

call(void troublesomeMethod());

}

81

CASCON '04

summary

join points pointcuts advice

method & constructor -primitive- before

call call after

execution execution around

field handler inter-type decls

get get set Type.field

set initialization Type.method()

dispatch

exception handler this target args declare

execution within withincode error

initialization cflow cflowbelow parents

aspects -user-defined- precedence

pointcut declaration

crosscutting type reflection

abstract

thisJoinPoint

overriding

thisJoinPointStaticPart



82

CASCON '04

where we have been…

… and where we are going









problem structure

examples:

crosscutting in the design, and

how to use AspectJ to capture that



AspectJ language

language mechanisms:

crosscutting in the code

mechanisms AspectJ provides





83

CASCON '04

using aspects



• present examples of aspects in design

– intuitions for identifying aspects

• present implementations in AspectJ

– how the language support can help

– putting AspectJ into practice

• discuss style issues

– objects vs. aspects

• when are aspects appropriate?





84

CASCON '04

example

plug & play tracing





• simple tracing

– exposes join points and uses very simple advice

• an unpluggable aspect

– core program functionality is unaffected by the

aspect









85

CASCON '04

tracing without AspectJ

class TraceSupport {

static int TRACELEVEL = 0;

TraceSupport static protected PrintStream stream = null;

static protected int callDepth = -1;



static void init(PrintStream _s) {stream=_s;}



static void traceEntry(String str) {

if (TRACELEVEL == 0) return;

callDepth++;

printEntering(str);

}

static void traceExit(String str) {

if (TRACELEVEL == 0) return;

callDepth--;

printExiting(str);

}

class Point { }

void set(int x, int y) {

TraceSupport.traceEntry("Point.set");

this.x = x; this.y = y;

TraceSupport.traceExit("Point.set");

}

}

86

CASCON '04

a clear crosscutting

structure

TraceSupport all modules of the system use the

trace facility in a consistent way:

entering the methods and

exiting the methods









this line is about

interacting with

the trace facility







87

CASCON '04

tracing as an aspect

aspect PointTracing {

TraceSupport pointcut trace():

within(com.bigboxco.boxes.*) &&

execution(* *(..));



before(): trace() {

TraceSupport.traceEntry(tjp);

}

after(): trace() {

TraceSupport.traceExit(tjp);

}

}









88

CASCON '04

plug and debug

• plug in: ajc Point.java Line.java

TraceSupport.java PointTracing.java



• unplug: ajc Point.java Line.java







• or…









89

CASCON '04

plug and debug

//From ContextManager

public void service( Request rrequest, Response rresponse ) {

// log( "New request " + rrequest );

try {

// System.out.print("A");

rrequest.setContextManager( this );

// log( "New request " + rrequest );

rrequest.setResponse(rresponse);

rresponse.setRequest(rrequest);



// wront request - parsing error

int status=rresponse.getStatus();

// System.out.print(“A”);

if( status 0)

} catch( Throwable ex ) {



}

if(debug>0) log( "Error closing request " + ex); log("Error closing request " + ex);

// log( "Done with request " + rrequest );

// System.out.print("C");



}

return;

// log("Done with request " + rrequest);



// System.out.print("C");



90

CASCON '04

plug and debug

• turn debugging on/off without editing

classes

• debugging disabled with no runtime cost

• can save debugging code between uses

• can be used for profiling, logging

• easy to be sure it is off









91

CASCON '04

aspects in the design

have these benefits





• objects are no longer responsible for using

the trace facility

– trace aspect encapsulates that responsibility, for

appropriate objects



• if the Trace interface changes, that change is

shielded from the objects

– only the trace aspect is affected



• removing tracing from the design is trivial

– just remove the trace aspect





92

CASCON '04

aspects in the code

have these benefits

• object code contains no calls to trace

functions

– trace aspect code encapsulates those calls, for

appropriate objects



• if the Trace interface changes, there is no

need to modify the object classes

– only the trace aspect class needs to be modified



• removing tracing from the application is trivial

– compile without the trace aspect class







93

CASCON '04

tracing: object vs. aspect



• using an object • using an aspect

captures tracing captures the

support, but does consistent usage of

not capture its the tracing support

consistent usage by by the objects

other objects

TraceSupport TraceSupport









94

CASCON '04

tracing

using a library aspect

abstract aspect Tracing {

abstract pointcut trace();



aspect BigBoxCoTracing { before(): trace() {

TraceSupport.traceEntry(tjp);

pointcut trace(): }

within(com.bigboxco.*) after(): trace() {

&& execution(* *(..)); TraceSupport.traceExit(tjp);

}

before(): trace() { }

TraceSupport.traceEntry(

tjp);

aspect BigBoxCoTracing

}

extends Tracing {

after(): trace() {

TraceSupport.traceExit(

pointcut trace():

tjp);

within(com.bigboxco.*)

}

&& execution(* *(..));

}

}







95

CASCON '04

example

context-passing aspects





caller1

Service





caller2







workers need to know the caller:

• capabilities

• charge backs

• to customize result





worker 1 worker 2 worker 3



96

CASCON '04

context-passing aspects



caller1

Service





caller2







workers need to know the caller:

• capabilities

• charge backs

• to customize result





worker 1 worker 2 worker 3



97

CASCON '04

context-passing aspects



pointcut invocations(Caller c):

this(c) && call(void Service.doService(String));









98

CASCON '04

context-passing aspects



pointcut invocations(Caller c):

this(c) && call(void Service.doService(String));



pointcut workPoints(Worker w):

target(w) && call(void Worker.doTask(Task));









99

CASCON '04

context-passing aspects



pointcut invocations(Caller c):

this(c) && call(void Service.doService(String));



pointcut workPoints(Worker w):

target(w) && call(void Worker.doTask(Task));



pointcut perCallerWork(Caller c, Worker w):

cflow(invocations(c)) && workPoints(w);









100

CASCON '04

context-passing aspects



abstract aspect CapabilityChecking {



pointcut invocations(Caller c):

this(c) && call(void Service.doService(String));



pointcut workPoints(Worker w):

target(w) && call(void Worker.doTask(Task));



pointcut perCallerWork(Caller c, Worker w):

cflow(invocations(c)) && workPoints(w);







before (Caller c, Worker w): perCallerWork(c, w) {

w.checkCapabilities(c);

}

}







101

CASCON '04

a few beginner mistakes



• overuse

• misunderstanding interactions with

reflection

– the call pointcut captures call join points made

from code, not those made reflectively

– use execution to capture reflection









102

CASCON '04

a few beginner mistakes



• not controlling circularity of advice

– pointcuts sometimes match more than

beginners expect

aspect A {

before(): call(String toString()) {

System.err.println(tjp);

}

}



– use within or cflow to control circularity

aspect A {

before(): call(String toString())

&& !within(A) {

System.err.println(tjp);

}

}

103

CASCON '04

summary so far



• presented examples of aspects in

design

– intuitions for identifying aspects

• presented implementations in AspectJ

– how the language support can help

• raised some style issues

– objects vs. aspects









104

CASCON '04

when are aspects

appropriate?



• is there a concern that:

– crosscuts the structure of several objects or operations

– is beneficial to separate out









105

CASCON '04

… crosscutting



• a design concern that involves several

objects or operations

• implemented without AOP would lead

to distant places in the code that

– do the same thing

• e.g. traceEntry(“Point.set”)

• try grep to find these [Griswold]

– do a coordinated single thing

• e.g. timing, observer pattern

• harder to find these





106

CASCON '04

… beneficial to separate out



• exactly the same questions as for objects

• does it improve the code in real ways?

– separation of concerns

• e.g . think about service without timing

– clarifies interactions, reduces tangling

• e.g. all the traceEntry are really the same

– easier to modify / extend

• e.g. change the implementation of tracing

• e.g. abstract aspect reuse

– plug and play

• e.g. tracing aspects unplugged but not deleted







107

CASCON '04

good designs

summary





• capture “the story” well

• may lead to good implementations,

measured by

– code size

– tangling

learned through

– coupling

experience, influenced

– etc.

by taste and style





108

CASCON '04

expected benefits of using AOP



• good modularity, even in the presence

of crosscutting concerns

– less tangled code, more natural code, smaller

code

– easier maintenance and evolution

• easier to reason about, debug, change

– more reusable

• more possibilities for plug and play

• abstract aspects





109

CASCON '04

Part III



examples and demo

Part IV



conclusion

AOSD



• language design

– more dynamic crosscuts, type system …

• tools

– more IDE support, aspect discovery, refactoring, re-

cutting, crosscutting views…

• software engineering

– UML extension, finding aspects, …

• metrics

– measurable benefits, areas for improvement

• theory

– type system for crosscutting, faster compilation,

advanced crosscut constructs, modularity principles

• see also aosd.net

112

CASCON '04

AspectJ technology



• AspectJ is a small extension to Java

– valid Java programs are also valid AspectJ programs

• AspectJ has its own compiler, ajc

– runs on Java 2 platform (Java 1.3 or later)

– produces Java platform-compatible .class files

(Java 1.1 - 1.4)

• AspectJ tools support

– IDE extensions: Emacs, JBuilder, NetBeans, Eclipse

– ant tasks

– works with existing debuggers

• license

– compiler, runtime and tools are Open Source and free for

any use





113

CASCON '04

AspectJ on the web



• eclipse.org/aspectj

– documentation

– downloads

– user mailing list

– developer mailing list

– pointers elsewhere...









114

CASCON '04

summary



• functions  OOP  AOP

– handles greater complexity, provides more

flexibility…

– crosscutting modularity

• AspectJ

– incremental adoption package  revolutionary

benefits

– free AspectJ tools

– community

– training, consulting, and support for use





115

CASCON '04

credits



AspectJ is now* an Eclipse project

with notable work by



Ron Bodkin, Andy Clement, Adrian Colyer,

Erik Hilsdale, Jim Hugunin, Wes Isberg, Mik Kersten,

Gregor Kiczales







slides, compiler, tools & documentation are available at

eclipse.org/aspectj



* Originally developed at PARC, with support from NIST and DARPA.





116

CASCON '04


Related docs
Other docs by HC111110051613
2001_ComplexModulationSpectrum
Views: 0  |  Downloads: 0
Defining 20The 20Project 20Primary 20Goal
Views: 0  |  Downloads: 0
219 Dyslipidemia 202009
Views: 0  |  Downloads: 0
richmondnews
Views: 0  |  Downloads: 0
CEN6016 Chapter1
Views: 0  |  Downloads: 0
Protecting 20Workers Mendelsen
Views: 0  |  Downloads: 0
owb_10gR2_ukoug_nov12005_updated
Views: 0  |  Downloads: 0
BE ISE 3_to_8 Final31stMarch_2010
Views: 1  |  Downloads: 0
ANTECPapers1956to2004
Views: 1  |  Downloads: 0
gpa_summary_final
Views: 0  |  Downloads: 0
By registering with docstoc.com you agree to our
privacy policy

You are almost ready to download!

You are almost ready to download!