Skip to main content

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

Matt,

As part of my job, I am researching how to use the java 1.5 tools to perform bytecode instrumentation of classes for which the source code is unavailable. In the process I hit this "subclass loaded before superclass" problem, and I couldn't find any reference on how to circumvent it. When I learned that AspectJ 5 handles this problem I became curious in knowing how it was done, which is what motivated my initial question to this forum.

You mention that AspectJ resolves references to all supertypes before matching pointcuts, but how does it find the bytecode for the super-types? If the classes are loaded by a user-defined class loader (as in my example), the source bytecode can only be found via a class-loader-specific implementation that is not part of the ClassLoader API. For instance: in my example, MyClassLoader actually looks for files with special names in a special directory, and I don't expose the names/locations for these files in any of my ClassLoader APIs. Thus, all of MyClassLoader's methods that find the super-type bytes will actually *load* the respective classes into the JVM, making them unsuitable for use within the ClassFileTransformer.transform method in the java agent.

Finally, is it the case that there is no public literature on these implementation issues? That is, every implementor who solved this problem (AspectJ implementors included) used nonstandard or proprietary techniques?

 -Murali

PS: Incidentally, I've never used AspectJ myself, but I've read about it and am aware of some of its capabilities. Also, I am a software developer with less than 2 years of experience, which explains my naiveness regarding the state-of-the-art in Java land :-)

Matthew Webster wrote:
Murali,

This is what actually happens. The byte-code for class C is loaded and
passed to the weaver. Before attempting to match any pointcuts references
to all super-types (classes, interfaces and aspects) are resolved.
Therefore the weaver may actually have the byte-code for classes B and A
_before_ the JVM. This process is the same whenever weaving takes place
(compile, binary, load) which is very important.The reference to the JVM
specification is not quite correct:

        "Before a class is initialized, its direct superclass must be
initialized, ..."

There is documentation for using the AspectJ language, tools and APIs.
There is also some documentation to allow the extension of the compiler.
However we do not have detailed documentation on its design and
implementation.

Matthew Webster
AOSD Project
Java Technology Centre, MP146
IBM Hursley Park, Winchester,  SO21 2JN, England
Telephone: +44 196 2816139 (external) 246139 (internal)
Email: Matthew Webster/UK/IBM @ IBMGB, matthew_webster@xxxxxxxxxx
http://w3.hursley.ibm.com/~websterm/
Please respond to AspectJ developer discussions <aspectj-dev@xxxxxxxxxxx>
Sent by:        aspectj-dev-bounces@xxxxxxxxxxx
To:     "'murvaja'" <murvaja@xxxxxxxxxxx>, "'AspectJ developer
discussions'" <aspectj-dev@xxxxxxxxxxx>
cc:      
Subject:        RE: [aspectj-dev] How does AspectJ implement load-time
weaving?


Murali, the Java ?language? specification guarantees that the VM will
always load the superclass of a class before it loads the class itself. So
this situation can never arise.
 
See step 7 at
http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.4.2
for the details of how this is guaranteed.
 

From: aspectj-dev-bounces@xxxxxxxxxxx
[mailto:aspectj-dev-bounces@xxxxxxxxxxx] On Behalf Of murvaja (sent by
Nabble.com)
Sent: Thursday, January 05, 2006 9:31 PM
To: aspectj-dev@xxxxxxxxxxx
Subject: [aspectj-dev] How does AspectJ implement load-time weaving?
 
I've been trying to understand how AspectJ manages to match the '+'
pointcut construct at runtime for load-time weaving. The example I have in
mind is for the Hotspot JVM 1.5, with load-time weaving enabled through
the -javaagent option, and goes as follows.

Say I have a class hierarchy like this:

public class A
{
   public void foo(){}
}

public class B extends A
{
 
}

public class C extends B
{
    public void foo(){}
}

And I write a pointcut and advice as follows:

pointcut pc() : execution (* A+.foo() )

before() : pc() {
//weaving code here
...
}

According to the pointcut definition, all subclasses of A will match the
pointcut, so the load-time weaving should insert the weaving code at the
beginning of both A.foo and C.foo. This will happen at their respective
class-load times, that is, A.foo will be weaved when A is loaded and C.foo
will be weaved when C is loaded.

My question is, how does the weaver do this if C is loaded before A and B,
like in the following code (assume none of A, B or C can be loaded by the
system class loader) ?


public static void main (String args[])
{
   ClassLoader loader = new MyClassLoader();
   loader.loadClass("C");
}


At the time C is loaded, the weaver will have C's bytes at hand and will
have to decide whether to weave them or not. According to the pointcut
definition, the bytecodes should be weaved because C is of type A.
However, the weaver cannot know that at this time, because the C bytecode
only contains a reference to its direct superclass B (not A), and the
bytes for B are not yet available because B is not yet loaded.

Any leads? I've been trying to find documentation on this but to no avail.
Thanks in advance,

-Murali

View this message in context: How does AspectJ implement load-time
weaving?
Sent from the AspectJ - dev forum at Nabble.com.
_______________________________________________
aspectj-dev mailing list
aspectj-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-dev

_______________________________________________
aspectj-dev mailing list
aspectj-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-dev

Murali,

This is what actually happens. The byte-code for class C is loaded and
passed to the weaver. Before attempting to match any pointcuts references
to all super-types (classes, interfaces and aspects) are resolved.
Therefore the weaver may actually have the byte-code for classes B and A
_before_ the JVM. This process is the same whenever weaving takes place
(compile, binary, load) which is very important.The reference to the JVM
specification is not quite correct:

        "Before a class is initialized, its direct superclass must be
initialized, ..."

There is documentation for using the AspectJ language, tools and APIs.
There is also some documentation to allow the extension of the compiler.
However we do not have detailed documentation on its design and
implementation.

Matthew Webster
AOSD Project
Java Technology Centre, MP146
IBM Hursley Park, Winchester,  SO21 2JN, England
Telephone: +44 196 2816139 (external) 246139 (internal)
Email: Matthew Webster/UK/IBM @ IBMGB, matthew_webster@xxxxxxxxxx
http://w3.hursley.ibm.com/~websterm/
Please respond to AspectJ developer discussions <aspectj-dev@xxxxxxxxxxx>
Sent by:        aspectj-dev-bounces@xxxxxxxxxxx
To:     "'murvaja'" <murvaja@xxxxxxxxxxx>, "'AspectJ developer
discussions'" <aspectj-dev@xxxxxxxxxxx>
cc:      
Subject:        RE: [aspectj-dev] How does AspectJ implement load-time
weaving?


Murali, the Java ?language? specification guarantees that the VM will
always load the superclass of a class before it loads the class itself. So
this situation can never arise.
 
See step 7 at
http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.4.2
for the details of how this is guaranteed.
 

From: aspectj-dev-bounces@xxxxxxxxxxx
[mailto:aspectj-dev-bounces@xxxxxxxxxxx] On Behalf Of murvaja (sent by
Nabble.com)
Sent: Thursday, January 05, 2006 9:31 PM
To: aspectj-dev@xxxxxxxxxxx
Subject: [aspectj-dev] How does AspectJ implement load-time weaving?
 
I've been trying to understand how AspectJ manages to match the '+'
pointcut construct at runtime for load-time weaving. The example I have in
mind is for the Hotspot JVM 1.5, with load-time weaving enabled through
the -javaagent option, and goes as follows.

Say I have a class hierarchy like this:

public class A
{
   public void foo(){}
}

public class B extends A
{
 
}

public class C extends B
{
    public void foo(){}
}

And I write a pointcut and advice as follows:

pointcut pc() : execution (* A+.foo() )

before() : pc() {
//weaving code here
...
}

According to the pointcut definition, all subclasses of A will match the
pointcut, so the load-time weaving should insert the weaving code at the
beginning of both A.foo and C.foo. This will happen at their respective
class-load times, that is, A.foo will be weaved when A is loaded and C.foo
will be weaved when C is loaded.

My question is, how does the weaver do this if C is loaded before A and B,
like in the following code (assume none of A, B or C can be loaded by the
system class loader) ?


public static void main (String args[])
{
   ClassLoader loader = new MyClassLoader();
   loader.loadClass("C");
}


At the time C is loaded, the weaver will have C's bytes at hand and will
have to decide whether to weave them or not. According to the pointcut
definition, the bytecodes should be weaved because C is of type A.
However, the weaver cannot know that at this time, because the C bytecode
only contains a reference to its direct superclass B (not A), and the
bytes for B are not yet available because B is not yet loaded.

Any leads? I've been trying to find documentation on this but to no avail.
Thanks in advance,

-Murali

View this message in context: How does AspectJ implement load-time
weaving?
Sent from the AspectJ - dev forum at Nabble.com.
_______________________________________________
aspectj-dev mailing list
aspectj-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-dev

_______________________________________________
aspectj-dev mailing list
aspectj-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-dev



View this message in context: RE: How does AspectJ implement load-time weaving?
Sent from the AspectJ - dev forum at Nabble.com.

Back to the top