Bil
For a custom classloader implementing bytecode instrumentation, the BCEL
sample or the AspectWerkz WeavingClassLoader are suitable.
But you cannot rely on them to work with user defined class loaders, and
as you pointed it, to work with scheme where bytecode is somewhere (over
the networrk or whatever).
Since your primary goal was to allow bytecode instrumentation no matter
the classloader implementation - including support for classloader
hierarchy as in J2EE space, you have from what I know the following
options:
- replace the java.lang.ClassLoader with a custom one (legal issue if
-Xbootclasspath/p is use, use HotSwap when possible)
- use JVMPI ClassLoadHook event (a bit limited)
- use JVMTI / Instrumentation under java 1.5
- use BEA JRockit JMAPI
- hack a custom JVM
The first four options are covered by AspectWerkz hooking architecture as
I already said. The "WeavingClassLoader" is only use for simple
applications relying on a single classloader.
I think the BCEL sample classloader allow to start with "class load time
instrumentation", but I don't think it is in the scope of BCEL to provide
a "universal" hooking mechanism.
I suggest you post AspectWerkz related question to AspectWerkz mailing
list. Here are some short answers:
- defineClass is (are) final, you cannot override it by subclassing
java.lang.ClassLoader
- one of AspectWerkz way of doing it is instrumenting the
java.lang.ClassLoader defineClass (defineClass0 is native, so it cannot be
altered).
- it really work - don't mismatch classloader delegation andd OO
inheritance from java.lang.ClassLoader
Alex
>
> Alex,
>
> Thank you for your advice! It makes sense, although I
> don't quite understand what's going on...
>
> My current classloader is based on the BCEL example
> code. It works fine, except for when the user uses
> his own classloader.
>
> Unfortunately, I don't totally understand why they
> wrote it that way. And, I don't quite understand why
> you wrote your WeavingClassLoader the way you did...
>
> In particular, I don't want to affect where the code
> is coming from. In the BCEL example, they write:
>
>
> protected Class findClass(String className, boolean instrument) {
> JavaClass javaClass = Repository.lookupClass(className);
> ...
> javaClass = Debugify.debugifyClass(javaClass, className); // do
> theinstrumentation
> byte[] b = javaClass.getBytes();
> clazz = defineClass(className, b, 0, b.length);
> return clazz;
> }
>
>
> and you have something very similar:
>
> protected Class findClass(String name) throws ClassNotFoundException {
> String path = name.replace('.', '/').concat(".class");
> Resource res = new URLClassPath(getURLs()).getResource(path, false);
> ...
> byte[] b = res.getBytes();
> byte[] transformed = ClassPreProcessorHelper.defineClass0Pre(this, name,
> b, 0, b.length, null);
> return defineClass(name, transformed, 0, transformed.length);
> }
>
>
>
> The bit I'm confused about is the Repository/Resource. Won't
> that affect where the class is loaded from? So if the user
> writes a weird classloader that just creates a byte array
> "magically", our R/R will miss that. (right?)
>
> So shouldn't we be delegating the findClass() stuff to the
> existing classloaders? They would then come up with the
> byte array and hand that to defineClass(). Our classloaders
> would specialize defineClass() to include the instrumentation
> and pass the transformed byte array to super.defineClass(),
> which would finally turn the byte array into a class.
>
> Does that make sense?
>
> (I've read all I could find on classloaders, but it's still
> less then 100% clear.)
>
> ================
>
> Looking through your Plug stuff, it looks like you're instrumenting
> java.lang.ClassLoader to do instrumentation in all the
> define0() methods (yes?). And that's equivalent to what I
> said above wrt defineClass()?
>
> ================
>
> Finally, does this really work? If a user defines a classloader
> which has the bootstrap classloader as parent, will your
> enhanced classloader be used?
>
>
>
>
> Sincerely,
>
>
> -Bil
>
>
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]