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

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


Back to the top