Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-dev] InvalidClassException during load time weaving

Thanks to both Simone and Andy for their comments. I agree with Simone
too, but I have to live with the legacy code that might not have
defined SUIDs.

Andy's observation that not using thisJoinPoint avoids this problem
may help. I will check if I can gather the runtime info I need without
using thisJoinPoint.

Thanks again,
Choudary Kothapalli.

On Tue, Jan 20, 2009 at 12:52 PM, Andy Clement <andrew.clement@xxxxxxxxx> wrote:
> I agree with everything Simone said about really requiring a
> serialVersionUID if implementing serializable - in fact AspectJ will
> generate the serialVersionUID fields for you with:
>
> ajc -XaddSerialVersionUID *.java
>
> (the field is calculated prior to weaving occurring).
>
> But of course that only works if compiling from source though and here
> you are consuming someone elses code.
>
> But your situation intrigued me so I had a dig into it.  You would be
> fine if you didn't reference thisJoinPoint.  This aspect:
>
> package mn
> public aspect TestAspect {
>       pointcut allExecutions():(execution(public * *.*(..))) &&
> !within(mnj.TestAspect);
>
>        Object around(): allExecutions(){
> //                System.out.println(thisJoinPoint);
>                return proceed();
>        }
>  }
>
> will not change the serial version UID.  All new members introduced
> are private and the type structure is unaltered.  The problem is that
> when you reference thisJoinPoint we are likely to add a static
> initializer to the affected type that will initialize the static parts
> of the join point object (so it is done once rather than every time
> the join point is encountered).  The creation of a static initializer
> where there wasn't one changes the serial version UID.  If the target
> type already had a static initializer, then the uid would not have
> changed, but you can't really rely on that...
>
> Andy.
>
>
> 2009/1/19 Choudary Kothapalli <choudary.kothapalli@xxxxxxxxx>
>>
>> Andy,
>>
>> Here is my simple aspect:
>> ----------
>> package mnj;
>> public aspect TestAspect {
>>        pointcut allExecutions():(execution(public * *.*(..))) &&
>> !within(mnj.TestAspect);
>>
>>        Object around(): allExecutions(){
>>                System.out.println(thisJoinPoint);
>>                return proceed();
>>        }
>> }
>> ---------
>> The test class is as follows:
>>
>> package test;
>> import java.io.*;
>> public class Tester implements Serializable{
>>        //private static final long serialVersionUID = 1L;
>>
>>        public String data = "testData";
>>
>>        public void write(String file) throws IOException{
>>                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
>>                oos.writeObject(new Tester());
>>        }
>>        public Tester read(String file) throws IOException, ClassNotFoundException{
>>                ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
>>                return (Tester)ois.readObject();
>>        }
>>        public static void main(String[] args) throws IOException,
>> ClassNotFoundException{
>>                String fileName = "data.ser";
>>                Tester tester = new Tester();
>>                //tester.write(fileName);
>>                tester.read(fileName);
>>        }
>> }
>> --------------
>> My scenario is as follows:
>> 1. The application serializes Tester (before aspect weaving). Tester
>> does not define SUID.
>> 2. Tester is weaved with TestAspect and deserialized.  It fails with
>> InvalidClassException. This is obviously because the Tester class
>> definitions differ (and generated SUIDs don't match) before and after
>> weaving.
>> 3. If the SUID is explicitly defined, they match and there is no problem
>>
>> As my product MaintainJ  is generic and should work with different
>> java runtimes, I cannot guess how the SUIDs are generated and avoid
>> affecting those classes. As I said in my first post, I can simply
>> avoid this problem by not weaving Tester class at all, but this
>> solution won't show the calls to those classes in the generated
>> sequence diagrams. Please let me know if you could think of any
>> workarounds.
>>
>> Regards,
>> Choudary Kothapalli.
>>
>> Here is the stack trace:
>> Exception in thread "main" java.io.InvalidClassException: test.Tester;
>> local class incompatible: stream classdesc serialVersionUID =
>> 5068263196426222505, local class serialVersionUID = 489981860994650887
>>        at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:546)
>>        at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1552)
>>        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1466)
>>        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1699)
>>        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)
>>        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)
>>        at test.Tester.read_aroundBody2(Tester.java:15)
>>        at test.Tester.read_aroundBody3$advice(Tester.java:109)
>>        at test.Tester.read(Tester.java:1)
>>        at test.Tester.main_aroundBody4(Tester.java:21)
>>        at test.Tester.main_aroundBody5$advice(Tester.java:109)
>>        at test.Tester.main(Tester.java:1)
>>
>> On Sun, Jan 18, 2009 at 9:52 PM, Andy Clement <andrew.clement@xxxxxxxxx> wrote:
>> > Tricky problem.  Are you able to limit what your aspect does such that it
>> > doesn't affect the parts of the classes that contribute to the calculated
>> > SUID?  If you are just using advice and not intertype declarations, I can
>> > imagine it might be possible - but then it would depend on perclauses, use
>> > of around advice and whether that advice can be inlined.  Do you know which
>> > part of your aspect is affecting the SUID?
>> >
>> > cheers,
>> > Andy.
>> >
>> > 2009/1/16 Choudary Kothapalli <choudary.kothapalli@xxxxxxxxx>
>> >>
>> >> My product MaintainJ instruments an application using load time
>> >> weaving to capture the call trace and generate the sequence diagram. I
>> >> am having problems while deserializing classes that do not define a
>> >> SUID. The SUIDs of the original class and the weaved class are not
>> >> matching and InvalidClassException is thrown.
>> >>
>> >> Currently I suggest my users to exclude those classes, but some
>> >> applications serialize too many classes and this solution is not ideal
>> >> for them. Any ideas on how this problem can be solved?
>> >>
>> >> Thanks,
>> >> Choudary Kothapalli.
>> >> _______________________________________________
>> >> 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