[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[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.