vipul_pandey (2) [Avatar] Offline
#1
Hi Ramnivas,

I recently bought your book and started exploring it.
Im finding it very intresting. Congratulations! on the job well done.

I am facing a very weird problem in one of my advice though.

I was trying to achieve Delegation using inheritance & AOP.
might sound weird at the first shot.

I have a superclass and its subclass.
I get a preprepared superclass object (SU1) (from my database interface.. or wherever) .... i wanted to create a subclass object (SBxSU2) and forward all the inherited method calls to SU1 instead of SU2 without writing wrapper method for each method in the superclass.

my subclass has a reference of type superclass which i assign to SU1 and forward all the method calls to SU1 instead of letting them go to 'super' object (SU2).

My aspect definition for the same looks like this :
(my get methods are all named getStr1,getStr2....getStr15 etc)

====================================
Class clazz = SuperClass.class;

pointcut getMethods(SubClass subClass) :
call(* getStr*(..)) &&
target(subClass) &&
!within(getMethods);


Object around(SubClass subClass) : getMethods(subClass) {

// ************** PLEASE CONSIDERTHIS COMMENTED OUT STATEMENT
//` System.out.println(thisJoinPoint.getStaticPart());

String methodName = thisJoinPoint.getSignature().getName();

java.lang.reflect.Method method = null;
Class[] arr = new Class[0];
try{
method = clazz.getMethod(methodName,arr);
SuperClass superObject = subClass.getSuperObject();
// subclass has a reference to that pre-made superclass object

return (String)(method.invoke(subClass.getSuperObject(),null));
}catch(Throwable e1){
// Could not execute the method in superObject ... execute in the subclass
}
return proceed(subClass);

}
===========================================


this code runs only when i uncomment
//` System.out.println(thisJoinPoint.getStaticPart());
this statement ....

if i keep it commented ... it breaks at the very first shot ... and gives me the following error

Exception in thread "main" java.lang.IncompatibleClassChangeError
at com.apple.vipul.aspect.MyClass.getStr1_aroundBody1$advice(MyClass.java:73)
at com.apple.vipul.aspect.MyClass.main(MyClass.java:69)


Any Ideas?


Eclipse 2.1.1
AspectJ 1.1.4
OS : Mac OS X (10.3)

Thanks,
Vipul
ramnivas (171) [Avatar] Offline
#2
Re: java.lang.IncompatibleClassChangeError
Hi Vipul,

I am glad that you liked my book.

About the error you are getting, please file a bug to the aspectj bugs database. It probably has to do with certain optimizations related to this*JoinPoint not working correctly.

In your program, I notice a few things:
1. What happens if you change:
thisJoinPoint.getSignature().getName();
to
thisJoinPointStaticPart.getSignature().getName();

Whenever you can use thisJoinPointStaticPart, since
it is a lot cheaper (as discussed in the book).

2. !within(getMethods) won't get you the desired effect.
The within() pointcut takes a type name as the argument.

3. You may be able to simplify your advice as follows and avoid reflection completely:
pointcut getMethods(SuperClass superClass) :
call(* SubClass.getStr*(..)) &&
target(superClass) &&
!within(MyAspect);

Object around(SuperClass invocationTarget)
: getMethods(invocationTarget) {
SuperClass newTarget
= ((SubClass)invocationTarget).getSuperObject();
return proceed(newTarget);
}

Try it and let me know.

-Ramnivas
vipul_pandey (2) [Avatar] Offline
#3
Re: java.lang.IncompatibleClassChangeError
Hi Ramnivas,

Thanks for responding back.

>About the error you are getting, please file a bug to the aspectj bugs database.

i'll do that,Thanks. Surprisingly this error goes if i have that System.out.println anywhere in the advice ( and not just in the begining)...


2. regarding your point 2. ... what if i have multiple advices in the Aspect File, and i don't want to bypass only one and not the rest?

3. I tried your suggestion. but somehow its not working ...
gives me the following error :

Exception in thread "main" java.lang.ClassCastException
at com.apple.vipul.aspect.MyClass.getStr1_aroundBody1$advice(MyClass.java:75)
at com.apple.vipul.aspect.MyClass.main(MyClass.java:69)

i decompiled the generated code and it explains why ...


this is what the code looks like for getStr1

static final String getStr1_aroundBody0(SubClass subclass, JoinPoint joinpoint)
{
return subclass.getStr1();
}

static final Object getStr1_aroundBody1$advice(FirstAspect this, SuperClass invocationTarget, AroundClosure ajc_aroundClosure, JoinPoint thisJoinPoint, SuperClass newTarget, JoinPoint joinpoint)
{
System.out.println(joinpoint.getStaticPart());
System.out.println(thisJoinPoint.getClass().getName());
SuperClass superclass = ((SubClass)thisJoinPoint).getSuperObject();
SuperClass superclass1 = newTarget;
SuperClass superclass2 = superclass; // superclass2 is ACTUALLY SuperClass type and not Subclass

return getStr1_aroundBody0((SubClass)superclass2, invocationTarget); // Here goes the casting which is not valid ....
}


if you look at my comments towards the end ... here it tries to cast a superclass object into subclass objet .... which fails ....

Regards,
Vipul