Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-dev] Can I intercept before a class is load time weaved

Hi Andy,

It is working! I just tried on a sample and it works like a charm. One
MaintainJ user has been waiting for this solution for months! Anyway,
better late than never.

Thank you very much.
Choudary.

On Sun, Sep 20, 2009 at 2:03 PM, Andy Clement <andrew.clement@xxxxxxxxx> wrote:
> I haven't tried it, but from the code this looks like it would work
>
> <weaver options="-XaddSerialVersionUID"/>
>
> if that doesn't work, let me know and we'll fix it up.  Sorry I didn't
> think of this earlier when you were describing your problem, it is
> what the feature was designed for.
>
> cheers
> Andy
>
> 2009/9/20 Choudary Kothapalli <choudary.kothapalli@xxxxxxxxx>:
>> But I am using load time weaving and I do not see
>> -XaddSerialVersionUID  supported at LTW. Is it?
>>
>> Thanks,
>> Choudary.
>>
>> On Fri, Sep 18, 2009 at 6:38 PM, Andy Clement <andrew.clement@xxxxxxxxx> wrote:
>>> No, if you specify -XaddSerialVersionUID then AspectJ creates the SUID
>>> based on the structure of the type prior to weaving.  Have you tried
>>> it out?
>>>
>>> public class A {
>>> }
>>> javac A.java
>>> serialver A
>>> A:    static final long serialVersionUID = -5362330504532103641L;
>>>
>>> // introduce an aspect that would change it
>>> aspect X {
>>>  public int A.i;
>>> }
>>> ajc A.java X.java
>>> serialver A
>>> A:    static final long serialVersionUID = -7845631417099584748L; // changed
>>>
>>> // ask aspectj to create the SUID
>>> ajc -XaddSerialVersionUID -Xlint:warning A.java X.java
>>> N:\temp\A.java [warning] calculated SerialVersionUID for type A to be
>>> -5362330504532103641L
>>> serialver A
>>> A:    static final long serialVersionUID = -5362330504532103641L; //
>>> returning field created by AspectJ
>>>
>>> Andy
>>>
>>> 2009/9/18 Choudary Kothapalli <choudary.kothapalli@xxxxxxxxx>:
>>>> Andy,
>>>>
>>>> Yes. But AspectJ does that after weaving the class. I do before
>>>> weaving. After the class is weaved, fields may be added to a class,
>>>> which generates a different SUID. The detailed problem description is
>>>> in this thread:
>>>> http://dev.eclipse.org/mhonarc/lists/aspectj-dev/msg02498.html
>>>>
>>>> Thanks,
>>>> Choudary.
>>>>
>>>> On Wed, Sep 16, 2009 at 5:44 PM, Andy Clement <andrew.clement@xxxxxxxxx> wrote:
>>>>>> To fix this, before passing the class to the weaver, I am checking if
>>>>>> SUID is not defined in a Serializable class and if so, I am inserting
>>>>>> one. That seems to solve my problem.
>>>>>
>>>>> Isn't that in fact a description of what the AspectJ
>>>>> -XaddSerialVersionUID option does?
>>>>>
>>>>> Andy
>>>>>
>>>>> 2009/9/13 Choudary Kothapalli <choudary.kothapalli@xxxxxxxxx>:
>>>>>> Hi Simone and Martin,
>>>>>>
>>>>>> Thanks for your pointers. I thought if I were going to write code at
>>>>>> byte code and class loader level, I would rather solve my problem than
>>>>>> implementing a work around. Here is what I did.
>>>>>>
>>>>>> Remember my original problem was because of a mismatch between SUIDs
>>>>>> when AspectJ deserializes a class without SUID defined. The default
>>>>>> Java generated SUID was not matching with the SUID of the AspectJ
>>>>>> weaved class.
>>>>>>
>>>>>> To fix this, before passing the class to the weaver, I am checking if
>>>>>> SUID is not defined in a Serializable class and if so, I am inserting
>>>>>> one. That seems to solve my problem. I have changed
>>>>>> org.aspectj.weaver.loadtime.Aj.preProcess(String className, byte[]
>>>>>> bytes, ClassLoader loader) method for this and using my
>>>>>> aspectjweaver.jar instead of the original jar.
>>>>>>
>>>>>> The source is at http://maintainj.com/temp/suidbug/Aj.java . There are
>>>>>> some parts that I am not sure if I am doing right.
>>>>>>
>>>>>> a) It is about the temporary classloader I need so that I can load the
>>>>>> class and use ObjectStreamClass.lookup(clazz).getSerialVersionUID() to
>>>>>> find the SUID that Java would generate. For this I need to know the
>>>>>> application classpath. I am assuming (and it is working in a client's
>>>>>> Swing application) that the classloader instance passed to the
>>>>>> Aj.preProcess(...) is URLClassLoader and I am calling getURLs() to get
>>>>>> all the paths to search. I am passing null as the parent of my
>>>>>> temporary classloader as the class should not be loaded before passing
>>>>>> to the AspectJ weaver. Is this going to break in a J2EE environment?
>>>>>> Is there a better way to find the classpaths to search? I couldn't
>>>>>> find any temporary classloader implementation in your samples.
>>>>>>
>>>>>> b) Adding a field to a class in BCEL - While creating the
>>>>>> ConstantValue for SUID of long type, I am passing 2 as its length and
>>>>>> it is working. What does that length parameter really mean? The
>>>>>> javadoc seems to say that it is the content length in bytes and as
>>>>>> long is of 8 bytes, I gave 8 and it failed. I changed it 2 as that's
>>>>>> what some snippet of AspectJ code was doing.
>>>>>>
>>>>>> Thanks again for your time and patience in addressing my problem
>>>>>> though it really is not an AspectJ defect.
>>>>>>
>>>>>> Regards,
>>>>>> Choudary Kothapalli.
>>>>>> MaintainJ Inc.
>>>>>>
>>>>>>
>>>>>> On Fri, Jul 31, 2009 at 11:36 AM, Simone Gianni<simoneg@xxxxxxxxxx> wrote:
>>>>>>> Hi Choudary,
>>>>>>> Martin is absolutely right, you need to :
>>>>>>> - Implement your own classloader
>>>>>>> - Use the weaving adaptor from there
>>>>>>> - Decide which classes you want to pass to the adaptor and which you don't
>>>>>>> want to
>>>>>>> - To make this check, either use BCEL/ASM, or load the class in a temporary
>>>>>>> classloader
>>>>>>>
>>>>>>> This last point is what you are asking for, to use reflection instead of
>>>>>>> ASM/BCEL. You don't really have to, ASM/BCEL can quite easily check for the
>>>>>>> presence of a static field in bytecode, and it's much much faster than using
>>>>>>> reflection for this, but if you really want to, you can still load the class
>>>>>>> in a temporary classloader (you can use an URLClassLoader), check it there
>>>>>>> and the load it in your real classloader with or without passing it to the
>>>>>>> weaving adaptor. The problem is that playing with classloaders this way is a
>>>>>>> bit tricky;  not impossible or extremely difficult, just tricky, which means
>>>>>>> you could spend hours trying to figure out why things are not working as you
>>>>>>> expect before understanding what is really happening.
>>>>>>>
>>>>>>> If you want to, I have played a bit with AspectJ LTW classloading, you can
>>>>>>> find some stuff here
>>>>>>> http://svn.apache.org/repos/asf/labs/magma/trunk/maven-magma-plugin/src/main/java/org/apache/magma/tools/classloading/
>>>>>>> . What you find there is a way to pipe a number of transformations (AspectJ
>>>>>>> weaver -> OpenJPA enhancer -> Cobertura enhancer) and then load the
>>>>>>> resulting class in the final classloader (in my case a webapp classloader).
>>>>>>> It works in "pull mode", that is when the webapp classloader searches for a
>>>>>>> class, it will search for a resource a/b/C.class to load the bytecode. When
>>>>>>> this happen, the chain of transformers kick in, each pulling bytecode from
>>>>>>> the previous one, so that the bytecode travels from the .jar file, via
>>>>>>> aspectj, openjpa etc.. to the classloader requiring it.
>>>>>>>
>>>>>>> Some of these transformers (including AspectJ) uses temporary classloaders
>>>>>>> in the middle. Maybe you can use that as a starting point and the add proper
>>>>>>> "if" statements to bypass aspectj weaver for classes you don't need.
>>>>>>>
>>>>>>> The code that build the chain and uses it is found here
>>>>>>> http://svn.apache.org/repos/asf/labs/magma/trunk/maven-magma-plugin/src/main/java/org/apache/magma/tools/maven/MagmaJettyRun.java
>>>>>>> inside the execute() method.
>>>>>>>
>>>>>>> Hope this helps,
>>>>>>> Simone
>>>>>>>
>>>>>>> Choudary Kothapalli wrote:
>>>>>>>>
>>>>>>>> This question follows the thread on InvalidClassException while
>>>>>>>> deserializing classes without SUID. The link to that thread is
>>>>>>>> http://dev.eclipse.org/mhonarc/lists/aspectj-dev/msg02496.html .
>>>>>>>>
>>>>>>>> I could not get rid of the exception and my only solution is to
>>>>>>>> exclude all those Serializable classes without SUID. I ask my users to
>>>>>>>> exclude those classes in aop.xml, but in a large legacy application,
>>>>>>>> it is a tedious process. I need to find a simpler solution.
>>>>>>>>
>>>>>>>> A probable solution is to intercept just before weaving a class, check
>>>>>>>> if that class is Serializable without SUID and if so, not to weave it.
>>>>>>>> This would need two things:
>>>>>>>>
>>>>>>>> 1. Ability to intercept just before a class is load time weaved. In
>>>>>>>> this 'advice', the normal class should be available so that a check
>>>>>>>> can be made for SUID using java reflection.
>>>>>>>> 2. Ability to proceed without weaving if I don't want to weave that class.
>>>>>>>>
>>>>>>>> I don't find a way to do this currently. By the time
>>>>>>>> 'staticinitialization' is intercepted, the class may be weaved
>>>>>>>> already.
>>>>>>>>
>>>>>>>> Again, I don't think this is any problem with AspectJ. It is just
>>>>>>>> something I need and I am checking if you could offer any solution
>>>>>>>> with your knowledge of AspectJ implementation.
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Choudary Kothapalli.
>>>>>>>> _______________________________________________
>>>>>>>> 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
>>>>>>>
>>>>>> _______________________________________________
>>>>>> 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
>>>>>
>>>> _______________________________________________
>>>> 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
>>>
>> _______________________________________________
>> 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
>


Back to the top