Wednesday, February 25, 2004

dynamic AOP and HotSwap

(imported from http://blogs.codehaus.org/people/avasseur, read comments there)


In a recent post Bill Burke describes his preliminary research as regards HotSwap usage for dynamic AOP.




He first defines in a few words what is dynamic AOP and what is the HotSwap or class redefinition in Java. Then he briefly describes how JBossAOP handles
dynamic AOP thru a "prepare" phase, and gives some measurements about the overhead he obtained when using the -Xdebug mode during a JBoss startup sequence, an option required to activate the HotSwap API under Java 1.4.




I would like to give some feedback on his post, since I have been working in the dynamic AOP field for some time now thru my involvment in AspectWerkz and
thru a research paper and a runtime weaving prototype I did for the Dynamic Aspect Workshop for AOSD 2004.




I think dynamic AOP has to be splitted in two categories:


  • rearranging AOP constructs at existing join points

  • redefining join points (we could generalize with redefining pointcuts, or even redefining the whole AOP system)




The first category is fully supported by AspectWerkz. It is possible to rearrange (add/remove/reorder) aspects and advices at runtime providing that the join point(s) where the construct(s) is(are) bounded is(are) already existing as a result of the transformation phase, no matter it is a post compilation phase (ala AspectJ) or a class load time weaving.



As regards introductions, AspectWerkz allows to change the introduction implementation (thus the implementation of the added methods) at runtime (swap mixin implementation), again providing that the binding (which mixin(s) applies to which class(es)) is already existing.



This first category relies on the framework capabilities and several means allow to minimize the overhead when f.e. no advice is bounded at a particular join point.

The overhead even if minimal cannot be avoided here. Even reduced to a method call that does a boolean check, this is not the original bytecode instruction sequence which is running when the join point is reached.

This category is the one supported by JBoss as well.




The second category is the most interesting one. Redefining join points (thus pointcuts) allows - in theory - to add new AOP construct at new locations (join points) in the running application.
This should come with the guarantee that there is


  • absolutely no runtime overhead prior the "activation" of the new join points, and no overhead after "deactivation"

  • no assumption that the join points are known before activation (especially at class load time / application deployment time)





I think that this second category requires runtime weaving capabilities from the AOP framework (as long as the AOP frameworks rely on bytecode instrumentation).




A use-case for join point redefinition at runtime is some on-demand profiling tool that needs to activate profiling only when necessary, for a limited time, and without any overhead prior to activation, and without specific knowledge on what will be profiled at application deployment time.




As Bill explains, JBossAOP "addresses" the second category by providing a way to declare pointcuts with nothing bounded. This definition is used at class post compilation / class load time and is what Bill calls the "prepare phase".


The overhead involved by such an approach is not measured by Bill, but is conceptually limited to a boolean check and a method level indirection, this for each pointcuts declared for future activation.


I don't think this approach is really adressing dynamic AOP. The overhead at a single join point level is indeed minimal, but we might have a need to declare very invasive pointcuts to allow further on-demand profiling (or other AOP based constructs), and thus this minimal overhead might occurs trillions times in the running application (potentially at each method call, each method execution and each field access).




So what might be a better solution for true runtime join point redefinition ?




As Bill quotes, HotSwap API allows to change the implementation of method / constructor bodies of a class at runtime, and inject them in the running JVM.


There are some interesting things to consider, that Bill forgot to mention and led him to some approximative statements (I forgot to told him ;-) )


  • HotSwap is an optional JVM capability. Some JVMs do not have HotSwap support (f.e IBM JRE)

  • HotSwap might forbid class schema change. It might not be possible to add new methods (even private ones) to a class when redefining it. This schema change support is itself an optional HotSwap capabilitiy. Currently no JVM supports schema change, but the API does not restricts it.

  • HotSwap exists since Java 1.4, requires -Xdebug mode, and can only be called from a remote JVM (well almost, read below)

  • HotSwap is slightly modified in Java 1.5 and does not requires -Xdebug mode





So considering what HotSwap can do, and what bytecode instrumentation oriented AOP frameworks do to enable AOP in Java OOP, especially to enable dynamic AOP constructs of the first category I described previously, HotSwap seems very attractive, but is currently missing key things.


There might be some ways to address the problems thought...





The fact that the java level HotSwap API as described in Java 1.4 JPDA requires a remote JVM attached to the running JVM (or a JPDA LaunchingConnector) can be avoided by implementing a JNI layer on top of the C-level HotSwap API so that HotSwap is available at Java level, without coupling with the JPDA architecture: no need for a remote JVM, and no need for a LaunchingConnector (that would forbid further remote dedbugging ...).


I describe the advantage of this JNI glue in the work I submitted to the DAW AOSD 2004, and call it "in-process HotSwap". We have it in Java 1.5 so there is no problem on this side anymore.




The "in-process HotSwap" - Java level API - is standardized in Java 1.5 thru the JSR-163. Java 1.5 will not requires -Xdebug to enable the HotSwap API. As you might have understood, the HotSwap API is not that coupled to the JVM debugging capabilities, althought the API was part of the same block in Java 1.4.


The -Xdebug overhead issue raised by Bill is fixed (though I would like to do measurement of what -Xjavaagent in Java 1.5 involves).




The schema change support would be interesting for AOP join point redefinition, since as Bill explains, AOP frameworks that allow dynamic AOP (AspectWerkz, JBossAOP) require some structural changes to bring in enough indirection level between the join point (in the weaved classed) and the AOP constructs (handled by the AOP framework internals).




A simple bytecode decompilation of an AspectWerkz weaved class with execution pointcut will show you that AspectWerkz has added a wrapper method to handle the join point and renamed the original method, since it will be called by the framework as a result of the execution join point construct.






class Foo {

public void doAction() {
// the bytecode for your code
}

}



can appeared transformed after the weaving as (approximation)




class Foo {

JoinPointManager __AW_joinPointManager =...

public void doAction() {
__AW_joinPointManager.proceed(this, "doAction()");
}

private void __AW_doAction() {
// the bytecode for your code
}
}



As a consequence, if we would like to be able to redefine (f.e. simply define) the "* Foo.doAction(..)" execution pointcut at runtime, we would need schema change support. The schema change support might not be needed though for caller side constructs.


The problem is thus more a HotSwap API problem, tight to current JVM limited capabilities.




I think that HotSwap - if largely adopted by JVM implementation - can be a good enabler for dynamic AOP as regards pointcut redefinition at runtime. I don't think that the debate is limited to a -Xdebug option, and Java 1.5 demonstrates it.


In the work I submitted to the DAW AOSD 2004, I describe how we are able in an AspectWerkz prototype to redefine pointcuts at runtime even without schema change support.




I agree that this solution (which I will publish later in my blog) is itself not optimal but I was able to demonstrates the feasability of such an on-demand AOP approach, instead of an invasive pointcut definition, that might itself lead to a globally large overhead. I was able to do the prototype with Java 1.4, and it will be even more easy to do with Java 1.5 and the standardized "in-process" Java level HotSwap.


I will debate if HotSwap is good for dynamic AOP at the DAW AOSD workshop, and you bet, some more JVM level AOP support might be crucial on this area.



So far so good, what do we wanted ?




Probably not a low level "addPointcut(<pointcut pattern>, Class klass)" API with a controlled and guaranteed minimal (or even zero) global overhead prior activation, but maybe a more usefull system wide control like "addAOPSystem(ClassLoader klassScope, SystemDefinition definition)" to be able to activate AOP constructs as a whole, at runtime, and leaving the internal recipe of it to AOP solutions and JVM implementations ...





Right ?

Tuesday, February 17, 2004

It's life

(imported from http://blogs.codehaus.org/people/avasseur, read comments there)

Most of my blog' fans (do I have blog fans ?) might think I am hacking AOP constructs and weaving architecture all the day.

Well I have to admit that this is not exactly true, thought almost true ;-).

These days I had to hack a small app that gather data from a WebLogic Server farm (more than 60 servers) by querying runtime JMX mbean so that we can then generate some graph to feed a NOC intranet.
Rather simple to play with JMX, have a fault tolerant client that does not crash when one instance is downed, and be able to handle at least 10 Go log daily.

For now the logs are parsed and consolidated as regular file. I would have liked to use a MySQL or HSQL database instead of parsing Go of files... but well, it is a customer driven story.

Here is a pretty cool graph that I got using JFreeChart that shows some http session data history grabbed from a subset of the farm.
Fun ?

Click to enlarge

Tuesday, January 6, 2004

AspectWerkz AOP - new pointcut expression implementation

(imported from http://blogs.codehaus.org/people/avasseur, read comments there)

Today I finished my implementation of the new AspectWerkz pointcut expression language.

AspectWerkz had already a good usability level as regards pointcut expression. Most of the needed syntax to bind pointcuts with advice or introduction had been implemented by Jonas, based on an algebra backed by Jexl.


/** @Aspect perJVM */
public class MyAspect extends Aspect {

/** @Execution com.*.Foo.set(..) */
Pointcut pc1;

/** @Execution com.*.Foo.get(..) */
Pointcut pc2;

/** @Around pc1 OR pc2 */
Object advice(Joinpoint jp) { .. }

}


The previous implementation supported the complete AND / OR / NOT algebra:

pc1 OR pc2
pc1 AND ( pc2 OR pc3 )
pc1 AND NOT pc2
...

And some synonyms were also provided, like &&, || and !, and other lowercased operators (or, and, not).

What I found bad with this Jexl based implementation was the following:

  • very hard to add new syntax operator (like IN for cflow pointcut composition)

  • added a programmed AST on top of the Jexl AST, but without providing a true Visitor pattern exposure

  • lost boolean expression optimization f.e. needed to evaluate all pointcut in an OR expression like pc1 OR pc2 even if pc1 matched

  • used only a tiny part of Jexl capabilities (Jexl is the evaluation engine of Velocity)



After some digging in Jexl extensibility I decided to start my own boolean expression implementation based on a JJTree grammar. In two days I had the complete operator set I needed, and a true Visitor pattern exposure.

In other two days I was able to refactor Jonas' work to plug my JJTree implementation in AspectWerkz. It allowed to solve a pending issue we had in the 0.9.RC1 release as regards cflow support for model 2 JSR-175 style Aspects.

Now we have many advantages at the hand:

  • no impact for the user

  • faster, especially when boolean optimizations are possible

  • cleaner, with Visitor pattern

  • more usable: with the new cflow composition thru the IN operator



From a user point of view this grammar add a new operator for cflow: the IN and NOT IN (or ! IN etc ...).
It allows to express in a natural way the pointcut expression with cflow.
pc1 OR pc2 IN cflow1
is then different from
( pc1 OR pc2 ) IN cflow1
[ the previous syntax was not natural : pc1 && cflow1 ]

In the next month, I should have time to add the needed glue to support several level of cflow composition - since this is already supported by our JJTree grammar :
pc1 IN ( cflow1 OR ! cflow2 )

This time, the trick will be more at the runtime during the joinpoint evaluation.

Tuesday, December 16, 2003

An awfull backend for AOP vs AspectWerkz (part 1)

(imported from http://blogs.codehaus.org/people/avasseur, read comments there)

Today while having my daily googling time on AOP, I found a 25 pages article about JMangler, a class load time weaving solution I had already bloged about.

The paper is here as a PDF.

I am rather surprised when I read that and mirror it with the fact that AOP would gain from massive adoption. I will defend my position in a very near future, but i could not avoid this flameware snip.

JMangler quotes itself as A Powerful Back-End for Aspect-Oriented Programming. And you might even buy a Prentice Hall book in 2004 to learn that.
I will save your time and money, by explaining you (again) why AOP does not gain from such a low concrete achievement strategy.

Just to let you think about by your own while I am writting my flameware:

  • Will you buy a book in 2004 to learn that JMangler is used in AspectWerkz ? This is false: JMangler had been in AspectWerkz but has been kicked out since july 2003 and we are happy.

  • Have your read that AspectWerkz hooking provides native support for BEA JRockit ?

  • Have you already worked with IBM JRE class loading scheme

  • Should a powerfull solution - that claim to be compliant with J2EE - fail under WebSphere environments ?
  • Should a powerfull solution be SUN JRE 1.4 centric ?

  • Should it hang when used in J2EE architectures ?

  • Should it run only in -Xdebug mode, with two JVM side by side ?



Is that a joke ? Abusing the AOP hype in the Academic sphere ?
Software is a moving thing, and AspectWerkz makes AOP move fast. Be ready.

Friday, November 21, 2003

AOP debugging makes its show

(imported from http://blogs.codehaus.org/people/avasseur, read comments there)

Samuel has done a viewlet where he demonstrates how to easily debug an application and its aspects with AspectWerkz from within Eclipse.

If you did not yet understood how standard and easy it was from my first annoucement, you have to watch it now !

All is explained step by step. This is a definitely a things to work with.