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 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
>


Back to the top