Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Bug Collection + declare parents?

I agree with Alexander, and indeed when I compiled your code I saw the error I expected (AspectJ 1.8.5):

ajc -1.5 *.java *.aj
/Users/aclement/provaBug/ClassImplementingInterf.java:3 [error] The type ClassImplementingInterf must implement the inherited abstract method MyInterface.myMethod()
public class ClassImplementingInterf {

AspectJ wants to ensure the type system is consistent when you are applying ITDs. Here you have said a class implements an interface but you haven’t provided an implementation for the method, it is an error. In your more recent reply you said " If i had to implement directly the interface by hard coding it in the classes i can also specify an implements clause in the class declaration, isn't it?” - yes,  you could, but you don’t have to directly implement the interface by hard coding it in the class. You can use an ITD for it:


public aspect ConcreteAspect extends MyAspect {
        declare parents: ClassImplementingInterf implements MyInterface;

        // implementors of this interface not providing an implementation of this method will get this one
        public void MyInterface.myMethod(){
                System.out.println("myMethod");
        }

        pointcut mypointcut(): call(public void OtherClass.method(int));
        pointcut interfacemethod(): call(void *.*.myMethod());
}

So no changes required in ClassImplementingInterf.  This pattern above is very common.

I’m surprised you aren’t seeing errors like the one above, I wonder what compilation sequence you are using to build the pieces. Why haven’t I gotten around to implementing traits :)

cheers,
Andy


On Mar 5, 2015, at 2:33 AM, Savoja Luca <luca.savoja@xxxxxxxxxxxxxxxxx> wrote:

Hi and thanks for the reply,

Well I think that adding an interface with declare parents and not specifying an implementation is not a problem in AspectJ, 
if it were not so, what should serve declare parents? If i had to implement directly the interface by hard coding it in the classes i can also specify an implements clause in the class declaration, isn't it?

I know it's a strange behaviour to add an interface with aspectj and pretend that classes works as the interface was present, but i'm trying to create an aspect that implements the GoF command pattern (like in the work of Jan Hannemann and Gregor Kiczales https://www.cs.ubc.ca/labs/spl/projects/aodps.html )

And I want to underline that everything work fine except the implicit cast when extracting the ClassImplementingInferf instance from the collection.

I've made some other tests and i found out that
MyInterface var2 = (MyInterface)(ClassImplementingInterf)x.get(0);
Works fine, but
MyInterface fromLst = x.get(0);
throw ClassCastException

I think it's a strange behaviour!

I hope i was clearer.
Regards,
Luca


2015-03-04 20:46 GMT+01:00 Alexander Kriegisch <Alexander@xxxxxxxxxxxxxx>:
Hi Luca.

I am nowhere near a PC now, so I cannot run/test your code, but from what I see I am really surprised you do not get more errors earlier in the process because it just does not make sense to ITD-declare a class to implement an interface without also specifiying an actual implementation. I wonder why it even compiles. Don't you see any compilation errors? Maybe the class file just (partly) works by chance because Ajc has produces halfway usable bytecode before terminating.

Probably you will get more qualified feedback from Andy Clement or even from me when I have time to actually switch on my home office PC (which can be days from now). My hint is just quick and first-aidish.

Regards
--
Alexander Kriegisch
http://scrum-master.de


> Am 04.03.2015 um 17:05 schrieb Savoja Luca <luca.savoja@xxxxxxxxxxxxxxxxx>:
>
> Hello everyone,
>
> I found a situation where i get a ClassCastException that might not be thrown.
> With declare parents I force a class to implement an interface, in an aspect i put an object of this class in a collection of the interface's type. And everythig works fine thus far.
> Then when i extract the object from the collection i get a ClassCastException.
>
>
> Here's an example that illustrates what i'm describing you.
>
> I've a simple interface:
>
> public interface MyInterface {
>       void myMethod();
> }
>
> and a class that i force to implement it by declare parents.
>
> public class ClassImplementingInterf {
>       //if the the interface methods are present in the implementing class there's no cast error
>       /*
>       public void myMethod(){ //NB: commented, not present.
>               System.out.println("myMethod");
>       }
>       */
> }
>
> then I have an abstract aspect:
>
> public abstract aspect MyAspect {
>       private ArrayList<MyInterface> x = new ArrayList<MyInterface>();
>
>       abstract pointcut interfacemethod();
>       abstract pointcut mypointcut();
>
>       void around(): mypointcut(){
>               ClassImplementingInterf obj = new ClassImplementingInterf();
>
>               x.add(obj); //working
>               MyInterface var = (MyInterface) obj; //working
>               ClassImplementingInterf fromListWithCast = (ClassImplementingInterf) x.get(0); //working
>
>               System.out.println("Just before MyInterface fromLst = x.get(0)");
>               MyInterface fromLst = x.get(0); //ClassCastException
>
>               System.out.println("**** intercepted OtherClass.method ***** "); //not reached!
>       }
>
>       void around(): interfacemethod(){
>               System.out.println("**** intercepted interface method **** ");
>       }
> }
>
> and it's concrete aspect:
>
> public aspect ConcreteAspect extends MyAspect {
>       declare parents: ClassImplementingInterf implements MyInterface;
>
>       pointcut mypointcut(): call(public void OtherClass.method(int));
>       pointcut interfacemethod(): call(void *.*.myMethod());
> }
>
> and an other class (useless, i use it only for intercept the method)
> public class OtherClass {
>       public void method(int n){
>               System.out.println(n*2);
>       }
> }
>
> The main class is:
> public class ClassMain {
>       public static void main(String[] args) {
>               OtherClass o = new OtherClass();
>
>               MyInterface ci = new ClassImplementingInterf();
>               ci.myMethod(); //this works!! the class can act like it has the interface!
>
>               o.method(15);
>       }
> }
>
>
> As you can see i can put an ClassImplementingInterf instance in a MyInterface variable or collection, and I can also cast it to MyInterface.
> But when extracting it from a collection it doesn't work.
>
> I think there's some kind of reflective controls when extracting an element from a collection that fails when i do it.
> Sure enough if i add to ClassImplementingInterf a method that has the same signature of the interface the ClassCastException disappears and everything works fine.
>
> I've attached to this message a .rar package that contains my code.
>
> Best Regards,
> --
> Luca Savoja.
> <provaBug.rar>
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> To change your delivery options, retrieve your password, or unsubscribe from this list, visit
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users



--
Luca.
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users


Back to the top