Wednesday, July 30, 2003

AspectWerkz online architecture - better than JVMPI - Sun needs to think about it for java 1.5

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

I already talked about the coming AspectWerkz new architecture for online mode (on the fly weaving). The key advantages will be as I explained:
- java 1.3 support
- debug mode for JVM not required
- option for single jvm
You may think its useless since the online weaving is already working fine (almost) with JMangler 3.x, which came with the original terrific idea of hotswapping the java.lang.ClassLoader, but I can bet you will change your position once you will have played with it a little more, thru the official 0.8 release.

Today I gave a look at the JVMPI API. Its a C layer receiving events from the JVM. Two events could be usefull to handle for AOP implementations: JVMPI_EVENT_CLASS_LOAD (sent when a class is loaded in the VM) and
JVMPI_EVENT_CLASS_LOAD_HOOK (sent when the VM obtains a class file data, but before it constructs the in-memory representation for that class).

Coding a layer receiving JVMPI_EVENT_CLASS_LOAD_HOOK to transform the bytecode could be usefull, since it could be enabled with just a -XrunMyStuff option and a shared library. This is the approach many commercial or open source debugging and profiling tools have choosen.

But giving a deeper look implementing an AOP layer on it will fail shortly for the following reasons:
- the event does not give the caller classloader information
- it might be a hell to call the java implemented AOP layer (AspectWerkz off course) from the C/C++ MyStuff JVMPI addon. Unless we setup a kind of client / server mode with a protocol to transmit bytecode back and forth (see AdaptJ for this sort of things).
Could lead to the idea of a distributed weaving engine... but do you need it ? And how will we be able to handle the calller classloader distinction, for example to weave struts classes in a specifc war only ?

So I definetely think the JMangler idea was good, even if the implementation is not that much good. And thus I am sure the new AspectWerkz architecture which unleash the idea will be and is already killing...

JVMPI doc
adaptJ project
JMangler project

As a ending note, I am really surprised Sun implemented the JVMPI_EVENT_CLASS_LOAD_HOOK in JVMPI and not directly (and even both) in the java.lang.ClassLoader... since its almost the single issue an on the fly weaver has to solve... since we have to override a class of rt.jar for java 1.3 compatibility... since BEA has implemented it since more than 2 years (except for the system classloader, just for the custom classloader deploying application like ear, war, ejb-jar, rar, but this might change with WebLogic 9)... since several project tries to address this lack (JMangler, beSee, AspectWerkz, JBoss, AspectJ)

Sun engineers - wake up - put that stuff in java 1.5 - java AOP needs it !
Ready to make a lobby with me ?

Wednesday, July 23, 2003

beSee donated to AspectWerkz

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

Past 6 month I have founded and developped the beSee project. This project is now closed, but I am definitely happy since the core architecture is now part of AspectWerkz, founded by Jonas Boner, for which I am commiter.

AspectWerkz power will be unleashed in the next weeks, and let me explain why.

It all started with beSee-1-x. This project aimed to provide a runtime bytecode instrumentation solution for BEA WebLogic Server (v7), based on Javassist for bytecode instrumentation and BEA ClassPreProcessor feature, which allow to modify bytecode of deployed applications when they are loaded in the app server.
beSee-1-x allowed easy instrumentation, based on a property file, and provided JMX management feature for hot configuration. It was easy to instrument on the fly some classes and run a load test on my app.

But there was something missing: BEA ClassPreProcessor does not allow instrumentation of core server classes or jvm wide component, like a JDBC driver, so I was unable to instrument enough my CMPs to track down SQL query being executed.

I started beSee-2-x architecture. It provides a JVM wide PreProcessor hook, allowing to extend what BEA provided for deployed application to the whole JVM, and thus to any product running java (!).
I knew JMangler add this kind of feature, but after some testing it appeared to be heavy and not that much stable as regards app server integration (let me know and I will send you some test case for it, and read more, you'll learn why).

So the main features of beSee-2-x I implemented are:
- plugable JVM wide ClassPreProcessor mechanism for on the fly instrumentation
- bytecode kit independancy (BCEL and Javassist provided, any other supported)
- offline compiler (the AspectJ way)
- performance wise:
- beSee-2-x does not requires JVM to run in debug mode (JMangler does)
- beSee-2-x is java 1.3 compatible (JMangler is not)
- beSee-2-x auto adapts behavior for java 1.3 and 1.4 (process forking or hotswapping)
- beSee-2-x allow to disable dual process, thus a standard java ... command to launch the target application to instrument on the fly is enough - no need for a wrapper script and stream piping in background (required when hotswap or process forking is used).

beSee-2-x allowed me to unleash the power of beSee-1-x to the whole weblogic, not just the deployed app.
And crucial point, its open architecture was ready to unleash power and capabilities of next generation AOP framework - and AspectWerkz is the one !

So stay tune. All those features are right now in AspectWerkz CVS, and in some weeks, you won't feel the pain to plug AOP in your whole architecture, on the fly or offline, and with its full power - no debug mode required, java 1.3 supported, optional process forking (choose between tuning and easy set-up), not tight to any app server but certified app server ready.

BCEL patch submitted

(imported from http://blogs.codehaus.org/people/avasseur)

I have submitted a patch for the BCEL thread safe issue I described (read).

You'll find it on the BCEL dev mailing list archive. I am waiting for BCEL guy to put the patch in their CVS HEAD. For now you can whether incorporate the patch in the BCEL source and rebuild your own BCEL, or build a jar with only the two files I patched and put it in your classpath before the bcel.jar.

(read the post on the list archive)

(dowload the patch for BCEL 5.1)

Saturday, July 19, 2003

BCEL internal

(imported from http://blogs.codehaus.org/people/avasseur)

Using BCEL to do bytecode modification on a simple application I have, I encountered problems with thread safety. As soon as I got 2 threads instrumenting in parallel, the java Verifier begins to complains about generated method signatures.

I struggled half a day to find it out. Thread safety problem is not that easy to isolate. After some googling I found the following post on BCEL mailing lists

It appears that some of BCEL static class (org.apache.bcel.generic.Type and org.apache.bcel.classfile.Utiity at least), which should provides static method to compute human understandable signature from bytecode and vice-versa are miscoded.

If I understand that doing a thread safe application can be difficult, I am really thinking BCEL guy were lazy this time with a snip like

// sample purpose - pseudo code
package org.apache.bcel.classfile;

public abstract class Utility {

public static int consumed_chars;

public static String[] methodSignatureArgumentTypes(String) {
loop {
// read and set consumed_chars field
consumed_chars++;
}
}

public static String methodSignatureToString(String) {
loop {
// read and set consumed_chars field
consumed_chars++;
}
}

}


As we can see its obvious it is non thread safe because its bad designed: two static methods are using the same static field as a temporary storage to perform string operations.

I had to wrap the consumed_chars in a ThreadLocal and replace all calls. It works fine, but I cannot be sure I covered all the bad design BCEL put in.

Guy, ok to say BCEL is not designed for thread safety in the FAQ. But please try to avoid such ugly coding.

Another option for me could be to add some synchronized in my instrumentation application - but it would be a hell from a performance point of view.
Considering BCEL is used in app server modules (npulse, willy technology), it should be thread safe. In app server there is lots of classloading ocuring concurenlty (stub / skel generation, CMP impl at deployment time ...)