You are right of course, I was talking
about initialization and weaving does happen at load-time. It does, as Matt
correctly indicated, require the AspectJ weaver to load in some types before
their classes are loaded using BCEL (in fact the AspectJ weaver currently loads
all the classes this way and optimization is to find cases, like the bootstrap loader
loaded classes, where you can rely on reflection delegates that work on
classloader loaded classes), . My apologies for answering the wrong question.
From:
aspectj-dev-bounces@xxxxxxxxxxx [mailto:aspectj-dev-bounces@xxxxxxxxxxx] On Behalf Of murvaja (sent by Nabble.com)
Sent: Friday, January 06, 2006
1:11 AM
To: aspectj-dev@xxxxxxxxxxx
Subject: [aspectj-dev] RE: How
does AspectJ implement load-time weaving?
The 12-step process explained in your link refers to class
initialization (done after linking) and not loading. From what I know,
ClassLoader.loadClass("C") does not initialize C, it only loads it -
that is, it finds the source bytecode and creates a java.lang.Class.
Initialization of the class only occurs after the class is actually used in
execution code, as explained below.
http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.4
I know that the JVM specification guarantees the initialization of all
superclasses before the initialization of the class. However, by the time a
class is initialized it is already too late to change the bytecode. Hence, the
JVM 1.5 provides a hook at class *load* time, at a time when the superclass
might not have been loaded yet.
In order to uncover the order in which loading and bytecode transformation is
done, I implemented my own Java agent and attached it to a JVM running the
"main" code above. That, along with inspection of the JVM source code
implementation, suggested to me that things happen in the following order
(shown in pseudocode - I used curly braces to indicate a code block executing
within the body of the previous line):
loader.loadClass(C);
{
...
loader.findClass(C);
{
...
loader.defineClass(byte[] C_bytes); //these are the bytes
in class C's bytecode
{
...
transformer.transform(C_bytes);
// transformer is a ClassFileTransformer in my agent
loader.loadClass(B);
{
...
transformer.transform(B_bytes);
loader.loadClass(A)
{
...
transformer.transform(A)
}
}
}
}
}
This code flow indicates that loading C will indeed result in the loading of B
and A. However, the JVM class-load hook into C (that is, the transform method)
occurs before B or A are loaded. Thus, when inspecting C_bytes to determine
whether it extends A, I find that I have neither B_bytes nor A_bytes available.
What am I missing here? I assume something must be wrong somewhere in my
reasoning, otherwise AspectJ 5 wouldn't be able to provide its LTW capabilities
:-)
Thanks,
-Murali
View this message in context: RE:
How does AspectJ implement load-time weaving?
Sent from the AspectJ
- dev forum at Nabble.com.