340 likes | 440 Views
AspectWerkz 2 - and the road to AspectJ™ 5. Jonas Bon ér Senior Software Engineer BEA Systems. Outline. Overview Plain Java ™ AOP Integration Dynamicity Extensible Aspect Container AW Bench. Overview. Plain Java ™ AOP (synta x is JLS compatible) Annotation-defined aspects
E N D
AspectWerkz 2 -and the road to AspectJ™ 5 Jonas Bonér Senior Software Engineer BEA Systems
Outline • Overview • Plain Java™ AOP • Integration • Dynamicity • Extensible Aspect Container • AW Bench
Overview • Plain Java™ AOP (syntax is JLS compatible) • Annotation-defined aspects • Integrates well in J2EE environments • Load time, runtime and static weaving • Runtime deployment and undeployment of aspects • Open Source, founded Q4 2002 • Performance is comparable to ~ AspectJ™-XnoInline • Extensible Aspect Container
Overview • Pointcuts call(..), execution(..), set(..), get(..), cflow(..), cflowbelow(..), handler(..), staticinitialization(..), within(..), withincode(..),hasfield(..), hasmethod(..), args(..), this(..), target(..) • Life-cycle singleton, perthis(..), pertarget(..), perclass(..), percflow(..) • Intertype declarations (ITD) through Mixins(interface + methods implementing this interface) • Pointcut pattern language very similar to AspectJ™: <annotation>* <modifier>* <type> <type>.<name>(<type>*)
Plain Java AOP • JLS compatible • Annotation-defined aspects • Java 5 @Annotation(…) • Java 1.3/1.4 /**@Annotation(…) */ • Benefits • Does not break IDEs, tools etc. • Gives the impression of flattening out the learning curve (psychological effect) • Drawbacks: • JLS compatibility: can not break type-checking, f.e. ITDs • Less elegant and concise syntax
Code-style defined aspect -AspectJ 5 Plain Java AOP import foo.bar.Baz; aspect AsynchAspect { private ExecutorService m_threadPool = ... void around(): execution(void Baz.*(..)) { m_threadPool.execute(new Runnable() { public void run() { try { // proceed the execution in a new thread proceed(); } catch (Throwable e) { // handle exception } } ); } }
Annotation-defined aspect -AspectWerkz Plain Java AOP @Aspect class AsynchAspect { private ExecutorService m_threadPool = ... @Around(“execution(void foo.bar.Baz.*(..))”) void execute(JoinPoint jp) throws Throwable { m_threadPool.execute(new Runnable() { public void run() { try { // proceed the execution in a new thread jp.proceed(); } catch (Throwable e) { // handle exception } } ); } }
Annotation-defined aspect - AspectJ 5 Plain Java AOP @Aspect class AsynchAspect { private ExecutorService m_threadPool = ... @Around(“execution(void foo.bar.Baz.*(..))”) void execute(ProceedingJoinPoint jp) throws Throwable { m_threadPool.execute(new Runnable() { public void run() { try { // proceed the execution in a new thread jp.proceed(); } catch (Throwable e) { // handle exception } } ); } }
Annotation-driven AOP Plain Java AOP pointcut transactedOps() : execution(public void Account.credit(..)) || execution(public void Account.debit(..)) || execution(public void Customer.setAddress(..)) || execution(public void Customer.addAccount(..)) || execution(public void Customer.removeAccount(..)); pointcut transactedOps() : execution(@Transactional * *.*(..)); • Annnotion-based pointcuts can • Raise the abstraction level • Be more robust and predictable • Rely on standard annotations • EJB 3, JSR-250, JSR-181
Challenges Plain Java AOP • Challenges • Allow the user to have strong typed direct access to parameter values • Should be able to pass them on in the proceed(..)without wrapping them • Performance comparable with AspectJ™ 1.2
Challenges Plain Java AOP • Solutions • Use args(..) for parameter access • Custom proceed: user defines a custom JoinPoint interface and defines his own proceed(..) • Implementation of the interface is generated on the fly public interfaceMyJPextends JoinPoint { Object proceed(long[] l, String s); } @Around(..) Object advice(MyJP jp, long[] l, String s) { ... // modify the values return jp.proceed(l, s); }
Integration • Load time weaving • Deployment modules (aop.xml) • Proxy based weaving • XML-based pointcut definitions
Load-time weaving Integration • Classes are weaved when loaded • Pre Java 5 • JRockit™ pre-processor • Class loader patching (credit to JMangler) • Standardized in Java 5 • JVMTI (agents) • Implemented in AspectJ™ 5 • Java 5 using JVMTI agent • Java 1.3/1.4 using JRockit™ pre-processor
Deployment modules Integration • Need to control which aspects are used in which module (class loader) • Include or exclude aspects higher up in class loader hierarchy (or in my own module) => need for an AOP ‘deployment descriptor’ • Enabled through the aop.xml file • Is put in the META-INF directory in a JAR, WAR or EAR file • Implemented in AspectJ™ 5
Proxy-based weaving Integration • Create a proxy Target target = (Target)Proxy.newInstance( Target.class ); • Proxy for target class is created (on the fly) and weaved before returned • The target instance will now be advised by all the matching aspects (that are found in the class hierarchy) • Implemented for AspectJ™ 5
Proxy-based weaving Integration • Benefits • Very transparent and lightweight • Same performance as static weaving (much better than all other proxy implementations) • Same aspects and pointcuts can be used – no need for using Type+etc. • Good enough in many situations in J2EE environments • Drawbacks • Only ‘method execution’ pointcuts • Can not advise: • final methods • private methods
XML-based pointcut definitions Integration • AspectWerkz allows defining the whole aspect in XML (aop.xml) • Is very widely used by users • Had many benefits (f.e. no extra compilation step) • Powerful • Drawbacks • Sometimes too powerful • Error prone • Hard to keep consistent semantics • Solved in a better way in AspectJ™ 5 • More restricted but guarantees consistent semantics • Still does what most users want; provide definition for abstract pointcuts (e.g. “late binding”)
Sample: XML-based pointcut definitions Integration • Allows extending an abstract aspect • Needs to provide definition for allabstract pointcuts <aspectj> <aspects> <concrete-aspectname=“myaspects.DeploymentTimeAspect” extends=“lib.AbstractLibraryAspect”> <pointcutname=“abstractPointcut” expression=“within(com.biz..*)”/> </concrete-aspect> </aspect> </aspectj>
Dynamicity • Runtime deployment of aspects (runtime weaving) • Programmable per-instance deployment of aspects
Runtime weaving Dynamicity • ”Hot” deployment and undeployment of aspects • Based on HotSwap API • Atomic ’change sets’ • Support for rollback • Resulting code is staticallly woven
Sample: Runtime weaving Dynamicity public void enableMonitoring() { Deployer.deploy(ResponseTimeAspect.class); } public void disableMonitoring() { Deployer.undeploy(ResponseTimeAspect.class); } public void enableMonitoring(String pointcut) { String xmlDef = "<aspect>" + "<pointcut name=‘toMonitor' expression='" + pointcut + "'/></aspect>"; Deployer.deploy(ResponseTimeAspect.class, xmlDef); }
Challenges Dynamicity • Same performance for runtime deployed aspects as for regularly woven aspects • Zero overhead for target code after an aspect has been undeployed • Ensure consistent and atomic aspect deployments • At specific join point – “all or nothing”
Architecture Dynamicity • JoinPoint abstraction • Generated at runtime • Contains all data and logic for this join point • Has a public method: public static final invoke(…){…} • Inlined by VM • Also functions as the “closure” for around advice (can hold state etc.) • Weave in a call to this static method in the target class (replaces the join point “code block”) • Can swap the logic in the JoinPoint without affecting the target class
Limitations Dynamicity • HotSwap limitations: • New methods can not be added at runtime (supported in spec. but currently not in any impl.) • Means that execution pointcuts for around advice needs to be prepared (we add empty method) • Need wrapper methods to access private methods and fields in target class
Programmable per-instance deployment Dynamicity • Advice can be added to specific instance • Runtime deployment • Is pure per-instance (always ”this” instance) • Target classes must be ‘prepared’ • set to implement the Advisable interface • Credit to JBoss AOP • Drawbacks • Introduces a new API
Sample: Programmable per-instance deployment Dynamicity • Prepare the classes you might want to advise later <advisablepointcut-type="call|execution|set|get" expression="within(com.biz..*)"/> • Add advice to a specific instance (only) at runtime POJO pojo = new POJO(); ((Advisable) pojo).aw_addAdvice( "execution(@javax.ejb.TransactionAttribute)", newBeforeAdvice() { public void invoke(JoinPoint jp) { // start a new transaction } } ); Aspects.aspectOf(TxAspect.class).beginTx(jp);
Extensible aspect container Overview • Pluggable weaver • Support for different ’aspect models’ • Reference implementation supports • AspectWerkz • Spring AOP • AOP Alliance • AspectJ™ (not complete) • Dynamicity etc. to all aspect models • Weaver implementations • ASM • Javassist • JRockit™ VM weaving (prototype)
Architecture overview Extensible aspect container
Discussion Extensible aspect container • Why did we implement it? • Proof of concept for the merge with AspectJ™ • To ensure correct semantics when different frameworks co-exist (aspect precedence etc.) • To give (almost) equally good performance for all the ‘aspect models’
Performance Extensible aspect container • Spring aspects are executed • up to 13 times faster when running in the aspect container • Similar for all proxy based implementations • AspectJ™ aspects are executed • from equally fast (before/after/non-inlined around) • to 6 times slower (inlined around) • For details see the AW Bench microbenchmark suite
Benefits for AspectJ users Extensible aspect container • Production stable load-time weaving • Implemented in AspectJ™ 5 • Runtime deployment of aspects • Can reuse old AspectJ™ pointcut libraries
AW Bench Micro-benchmark suite • Compares the performance of major (industrial) AOP implementations • AspectJ, AspectWerkz, JBoss AOP, JAsCo, Spring, dynaop, cglib proxy • Currently tests: • All advice types (not ITDs) • Different kinds of context exposure (reflective and static) • execution pointcuts and singleton aspects only • Please contribute • with tests and/or new frameworks • More info: • http://docs.codehaus.org/display/AW/AOP+Benchmark
Links • Project home pages: • http://aspectwerkz.codehaus.org/ • http://eclipse.org/aspectj/ • Articles: • http://www.theserverside.com/articles/article.tss?l=AspectWerkzP1 • http://www.theserverside.com/articles/article.tss?l=AspectWerkzP2 • Benchmark: • http://docs.codehaus.org/display/AW/AOP+Benchmark • AspectJ™ 5 FAQ: • http://dev.eclipse.org/viewcvs/indextech.cgi/~checkout~/aspectj-home/aj5announce.html • JRockit™ home page: • http://commerce.bea.com/products/weblogicjrockit/5.0/jr_50.jsp
Questions...? Thanks for listening