Hi.

I agree with wes. It's weird.
I think class annotations for method signature is overrided just like
method annotations.

public aspect Test{
        declare warning : execution(void Base.func()) : "method";
        declare warning : execution(@Annot void Base.func()) : "methodAnnot";
        declare warning : execution(void (@Annot Base).func()) : "classAnnot";
        declare warning : execution(@Annot void (@Annot Base).func()) :
"methodAndClassAnnot";

        @interface Annot{}

        class Base{ void func(){} }

        @Annot
        class Derived extends Base{
                @Annot void func(){}
        }
}

From the code above, the class annotation is't overrided while method
annotation is.
Derived.func is marked as "method" and "methodAnnot". I think these should be
"method" and "classAndMethodAnnot".

Basically Derived.func has following signatures:
a. void Base.func()
b. @Annot void (@Annot Derived).func()
And through the matching processes in AspectJ, a. is treated as "void
Base.func()" and @Annot void Base.func()".

I think a. should be treated as "void Base.func()" and "@Annot void
(@Annot Base).func()".
Then the matching behavior becomes less weird (but still weird to me :).
I hope comming package and parameter annotations will be also treated as same
to method annotation.


takao.

2006/8/22, Wes <[EMAIL PROTECTED]>:
Ron's answer is good wrt why AspectJ is considering the methods in Object
as inherited by interface types, and that having nothing to do with annotations.
(But given the !Object workaround, I wouldn't exclude them by default.)

But your code raises a question wrt type patterns using annotations.

It just seems weird to me that 'execution(* (@Annot *).*(..))' picks out
methods not declared on the annotated type, even if they are inherited,
because annotations don't work that way.  Probably users should be writing

   pc() && within(@Annot *)

if they mean to restrict the execution join points to the annotated types.


In more detail...

Given a type T and its supertype ST (interface or class), I understand
that type T inherits the accessible methods in ST and thus

   execution(* T.stMethod(..))

matches for a method "stMethod" declared in ST (and not in T).

But the purpose of multiple signatures was to track method overriding, i.e.,
to use "execution(void ST.stMethod())" to pick out all overriding
implementations of stMethod().  (I'm less convinced the users intend
"execution(void T.*(..))" to pick out inherited methods, declared in the
supertypes of T but not in T.)

But let's say T has annotation A and ST does not, and we're matching

   execution(* (@A *).stMethod(..))

It's true that T matches (@A *), but imho there is no method-execution
join point signature that matches the pointcut signature.

The signatures (ignoring modifiers) could be

   void T.stMethod()   // by inheritance
   void ST.stMethod()  // by declaration

or just

   void ST.stMethod()

where T matches ST because T extends ST, but (@A *) would not match ST
even though T has annotation A, because ST does not have annotation A.

Put another way: although overriding is transitive wrt subtypes, annotations
are not.  Supertypes don't have the annotations in subtypes, and only
inherited annotations are in subtypes.  (As I recall, this was one of the
reasons we shied away from permitting modifiers in type patterns used in
signatures.)

So, would it make sense to restrict the set of signatures to those types
that actually declare the method, but permit any subtype to match
such signatures?  That could give us the overriding behavior but not
the unintended consequences of (@A *).stMethod(..)?

One workaround for now is to use && within(@A *), which works correctly
(e.g., not picking out implementations in unannotated subtypes), but
would not work for call join points.

Wes

------------Original Message------------
From: "Ron Bodkin" <[EMAIL PROTECTED]>
To: [email protected]
Date: Mon, Aug-21-2006 12:51 PM
Subject: RE: [aspectj-users] Why is toString matched?
Hi Brian,

AspectJ appears to be considering these methods as matching because they are 
defined on Object. In some sense AspectJ considers that MyInterface extends 
Object, just as in Java you can invoke methods on Object when you have an 
instance of an interface, without downcasting. You can work around this 
behavior by excluding methods defined on Object, e.g.,

    protected pointcut nonVoidMethod() :
        execution(public !void (@ServiceCallback *).*(..)) && !execution(* 
Object.*(..));

However, I think it would be better if AspectJ didn't consider methods defined 
on Object as being defined on an interface unless the interface explicitly 
declares them. So I think this should be a bug, although maybe there's a use 
case for why it should match?

Here's a similar program that shows the core issue without annotations (all the 
methods on MyInterfaceImpl):

public interface MyInterface {
   void doWork();
   int getValue();
}

class MyInterfaceImpl implements MyInterface {
   public void doWork() {}
   public int getValue() { return 0; }
   public String toString() { return "x"; }
}

aspect MatchMyInterface {
   declare warning: execution(* MyInterface.*(..)): "method on my interface";
}




From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of [EMAIL PROTECTED]
Sent: Monday, August 21, 2006 7:42 AM
To: [email protected]
Subject: [aspectj-users] Why is toString matched?


I'm trying to create a policy that enforces the following:

Any interface that is marked with the @Callback annotation cannot have methods 
that are non-void.

That is:

@Callback
public interface MyInterface {
   void doWork();
   int getValue();
}

public class MyInterfaceImpl implements MyInterface {
   void doWork() {...}                //   <---- just fine, as pectected
   int getValue() {...}                //   <---- expect error here, and it is
   public String toString() {...}           //   <---- should be just fine, but 
it's included in the joinpoint and thus an error
}

I've tried to accomplish this using the following joinpoint/error:

    protected pointcut nonVoidMethod() :
        execution(public !void (@ServiceCallback *).*(..));

    declare error : nonVoidMethod() :
        "Non void method.";

However, the results I get indicate that public String toString() matches this 
joinpoint.

In further experimentation, I redefined the interface:

@Callback
public interface MyInterface {
   void doWork();
//   int getValue();   note, I commented this out of the interface
}

and here's the results

public class MyInterfaceImpl implements MyInterface {
   void doWork() {...}                //   <---- just fine, as expected
   int getValue() {...}                //   <---- would expect the same 
behavior as toString exhibits.   However, this is not an error anymore
   public String toString() {...}           //   <---- still an error
}

I am a bit lost - why is the toString joinpoint included by my pointcut?   How 
do I prevent it?

Thanks,
Brian Yoffe


This communication is for informational purposes only. It is not intended as an 
offer or solicitation for the purchase or sale of any financial instrument or as an 
official confirmation of any transaction. All market prices, data and other 
information are not warranted as to completeness or accuracy and are subject to 
change without notice. Any comments or statements made herein do not necessarily 
reflect those of JPMorgan Chase & Co., its subsidiaries and affiliates.

This transmission may contain information that is privileged, confidential, legally 
privileged, and/or exempt from disclosure under applicable law. If you are not the 
intended recipient, you are hereby notified that any disclosure, copying, 
distribution, or use of the information contained herein (including any reliance 
thereon) is STRICTLY PROHIBITED. Although this transmission and any attachments are 
believed to be free of any virus or other defect that might affect any computer 
system into which it is received and opened, it is the responsibility of the 
recipient to ensure that it is virus free and no responsibility is accepted by 
JPMorgan Chase & Co., its subsidiaries and affiliates, as applicable, for any 
loss or damage arising in any way from its use. If you received this transmission 
in error, please immediately contact the sender and destroy the material in its 
entirety, whether in electronic or hard copy format. Thank you.
_______________________________________________
aspectj-users mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/aspectj-users

_______________________________________________
aspectj-users mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/aspectj-users

_______________________________________________
aspectj-users mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Reply via email to