[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
RE: [aspectj-dev] RE: How does AspectJ implement load-time weaving?

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.