Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-dev] Re: aspectj-dev Digest, Vol 48, Issue 5

Simone,
Sorry for the delay on the response.

Only after getting into the AspectJ Load Time Weaver source code I could understand it better and work the problem around.
We inserted some additional code to the ClassMock Class Loader so to make it work with load time weaving and it went smoothly, no problems till now.
We were trying to make it work only setting the java agent to the jvm. Using this approach, the runtime generated classes were being weaved correctly, but an exception occured always when the code was put to run. This exception did not interrupt the execution of the code though.

SEVERE: org/aspectj/weaver/UnresolvedType
java.lang.ClassCircularityError: org/aspectj/weaver/UnresolvedType
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at java.security.SecureClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.access$000(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
...

These are the changes we had to do on the Class Loader :

Prior to the changes, this was our Class Loader:

public class MockClassLoader extends ClassLoader {
    public Class defineClass(String name, byte[] b){
        return super.defineClass(name, b, 0, b.length);
    }
}

Now it looks like :

public class MockClassLoader extends ClassLoader {
    private static ClassPreProcessor classPreProcessor;
   
    static {
        try {
            classPreProcessor = new Aj();
            classPreProcessor.initialize();
        } catch (Exception e) {
            throw new ExceptionInInitializerError("Error initializing classPreProcessor");
        }
    }
   
    public Class defineClass(String name, byte[] b){
        byte[] weaved = classPreProcessor.preProcess(name, b, this);
        return super.defineClass(name, weaved, 0, weaved.length);
    }
}

As I said, it is till now working smoothly, showing no problems at all. When there are aspects to be weaved into the new runtime generated class, the classPreProcessor changes the byted code so to add the aspects code. If there are no aspects to be weaved into the bytecode, nothing happens.
I think though we still need some deeper studies to confirm that this approach won't result in a bug in the future.
If you think this solution won't work for every situation in somehow, please let me now so we can rush to find another way out

Thanks for all the help
Emmanuel Castro Santana

2009/3/17 <aspectj-dev-request@xxxxxxxxxxx>
Send aspectj-dev mailing list submissions to
       aspectj-dev@xxxxxxxxxxx

To subscribe or unsubscribe via the World Wide Web, visit
       https://dev.eclipse.org/mailman/listinfo/aspectj-dev
or, via email, send a message with subject or body 'help' to
       aspectj-dev-request@xxxxxxxxxxx

You can reach the person managing the list at
       aspectj-dev-owner@xxxxxxxxxxx

When replying, please edit your Subject line so it is more specific
than "Re: Contents of aspectj-dev digest..."


Today's Topics:

  1. Re: AspectJ load time weaving on runtime generated        classes
     (Simone Gianni)


----------------------------------------------------------------------

Message: 1
Date: Tue, 17 Mar 2009 13:15:05 +0100
From: Simone Gianni <simoneg@xxxxxxxxxx>
Subject: Re: [aspectj-dev] AspectJ load time weaving on runtime
       generated       classes
To: AspectJ developer discussions <aspectj-dev@xxxxxxxxxxx>
Message-ID: <49BF9449.3070507@xxxxxxxxxx>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

Hi Emmanuel,
well, it is a bit more complex, cause both the MockClassLoader and the
WeavingURLClassLoader are (as the names say :D ) class loaders, and Java
provide no infrastructure to concatenate more classloaders and have them
participate in bytecode rewriting, if not using agents.

I don't know why the agent is not working for you, have you tried
setting it up in the "normal way" using the -javaagent option on the
target JVM? It should intercept any bytecode definition, including those
performed by other classloaders, you sure you don't have a problem with
your pointcuts?

If that does not work or is not a viable way of setting up LTW, I used
another (rather radical) approach based on a chain of bytecode
transformers and a classloader that delegates to the chain. I did this
because I was not always in control of the java agents, and because for
a number of reasons too long to explain here and concerning the OpenJPA
enhancer, multiple agents were not cooperating properly.

The basic structure is that your application uses this classloader, when
your applications searches for a class the classloader calls the chain
that retrieves the raw bytecode (from another classloader, from a cache,
generating it on the fly should also be possible), and then passes
bytecode to the transformation chain, for example in my case it goes to
AspectJ weaver first and to OpenJPA enhancer then, and finally gets
defined in the JVM. All of this is configured creating a chain, setting
the classloader first, giving it a provider, giving that provider
another one, and so on.

I think this approach could work for you too, if you want to have a look
at the code it is here
http://svn.apache.org/repos/asf/labs/magma/trunk/maven-magma-plugin/src/main/java/org/apache/magma/tools/classloading/
, it's Apache 2.0 licensed so feel free to use it anyway you want. If
you want to see how I use it to setup a Jetty context using the chain i
described above, the class doing it is here
http://svn.apache.org/repos/asf/labs/magma/trunk/maven-magma-plugin/src/main/java/org/apache/magma/tools/maven/MagmaJettyRun.java
. I'm sorry I didn't yet have the time to write a lot of comments :D,
let me know if you need help, also privately or on the
labs@xxxxxxxxxxxxxxx mailing list if you feel it does not fit here.

I do understand this is a radical approach, dealing with classloading is
always a bit of a mess, but since you already started doing it on your
own, maybe what I have already done and tested may be useful.

Simone



Simone Gianne,
Thanks for the response.
My objective is to do weaving in asm (http://asm.objectweb.org/) runtime
generated classes. I am using a class generation framework called
classmock, it uses asm to generate classes at runtime. ClassMock
(http://classmock.sourceforge.net/) creates a bytearray with the new
class's bytecode and then uses it´s own ClassLoader to define the new
class to the JVM, like follows :

package net.sf.classmock;

public class MockClassLoader extends ClassLoader {

   public Class defineClass(String name, byte[] b){
       // need to do the weaving here
       return defineClass(name, b, 0, b.length);
   }

}

I need to do the weaving before defining this class to the JVM.
So I am trying to call the classes that perform the weaving before
calling the defineClass Method.
I have already tried using the WeavingURLClassLoader and the
org.aspectj.weaver.loadtime.Agent class, but till the current moment,
have got no success.
If you have got any tips about how this can be achieved, I would be glad
to know.
Thanks in advance.

Emmanuel Santana


   Message: 2
   Date: Thu, 12 Mar 2009 21:52:59 -0300
   From: Emmanuel Castro Santana <emmanuel.csantana@xxxxxxxxx
   <mailto:emmanuel.csantana@xxxxxxxxx>>
   Subject: [aspectj-dev] AspectJ load time weaving on runtime generated
          classes
   To: aspectj-dev@xxxxxxxxxxx <mailto:aspectj-dev@xxxxxxxxxxx>
   Message-ID:
          <acf51e320903121752oe3cd1daif033f1c0432c92fc@xxxxxxxxxxxxxx
   <mailto:acf51e320903121752oe3cd1daif033f1c0432c92fc@xxxxxxxxxxxxxx>>
   Content-Type: text/plain; charset="iso-8859-1"

   Good evening,
   I would like to know if it is possible to apply aspects on runtime
   created
   classes.
   I have been trying this days and still have got no luck.

   Thanks in advance,
   Emmanuel de Castro Santana
   -------------- next part --------------
   An HTML attachment was scrubbed...
   URL:
   https://dev.eclipse.org/mailman/private/aspectj-dev/attachments/20090312/21450c4b/attachment.html

   ------------------------------

   Message: 3
   Date: Fri, 13 Mar 2009 03:47:50 +0100
   From: Simone Gianni <simoneg@xxxxxxxxxx <mailto:simoneg@xxxxxxxxxx>>
   Subject: Re: [aspectj-dev] AspectJ load time weaving on runtime
          generated       classes
   To: AspectJ developer discussions <aspectj-dev@xxxxxxxxxxx
   <mailto:aspectj-dev@xxxxxxxxxxx>>
   Message-ID: <49B9C956.1080002@xxxxxxxxxx
   <mailto:49B9C956.1080002@xxxxxxxxxx>>
   Content-Type: text/plain; charset=ISO-8859-1; format=flowed

   Hi Emmanuel,
   it is possible if using LTW and if the "byte code chain" is working
   correctly. That means if the weaver gets a chance to weave the generated
   classes while they are being loaded in the target classloader.

   I run some experiments some time ago using cglib to generate runtime
   method interceptors and seeing if they got weaved or not, and in my
   situation it was working correctly.

   Also, I currently have in my Magma Apache Lab, OpenJPA enhancing classes
   after AspectJ weaved it, or the other way around (and when running tests
   also Cobertura comes into play with its enhancer) but had to setup a
   custom classloader and a quite a number of support classes to have this
   double/triple enhancing process to work smoothly.

   Can you elaborate on which kind of environment you are using? Are in in
   LTW? Are you using the agent? Which library is generating classes at
   runtime?

   Simone

   Emmanuel Castro Santana wrote:
    > Good evening,
    > I would like to know if it is possible to apply aspects on runtime
    > created classes.
    > I have been trying this days and still have got no luck.
    >
    > Thanks in advance,
    > Emmanuel de Castro Santana
    >
   ------------------------------------------------------------------------
    >
    > _______________________________________________
    > aspectj-dev mailing list
    > aspectj-dev@xxxxxxxxxxx <mailto:aspectj-dev@xxxxxxxxxxx>
    > https://dev.eclipse.org/mailman/listinfo/aspectj-dev
    >





--
Emmanuel de Castro Santana

------------------------------------------------------------------------

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



--
Simone Gianni            CEO Semeru s.r.l.           Apache Committer
http://www.simonegianni.it/



------------------------------

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


End of aspectj-dev Digest, Vol 48, Issue 5
******************************************



--
Emmanuel de Castro Santana

Back to the top