Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
RE: [aspectj-users] AW: Pointcut on a constructor withacustom@Annotation

Dean, I think you mean call( @MyAnnotation *.new(..) ) (or just
call(@MyAnnotation new(..))), since there's no return type for a
constructor.

In general, static and dynamic matching can behave a little differently,
although for constructors the differences can be a bit subtle. I tried a few
permutations Wes's suggested way of matching annotations based on the static
type. It looks like in this case they are exactly equivalent (so it's nicer
than my suggestion of testing the annotations on the returned object).
However, I found the results to be a little surprising. Consider:

import java.lang.annotation.*;

@Retention(value=RetentionPolicy.RUNTIME)
@interface I {}
@I class AnnotatedBase {}
class C extends AnnotatedBase {
    public @I C() {}
}

aspect A { 
  declare warning : call((@I *).new(..)) : "I new call"; 
  declare warning : call((@I *)+.new(..)) : "I new call, indirectly"; 
  declare warning : call(@I new(..)) : "I new call on ctor"; 
  before(Object obj) : @target(I) && target(obj) && execution(new(..)) {
System.out.println("I new exec with @target "+obj); }
} 

public class AnnotatedCtor {
  public static void main(String[] a) {
    new AnnotatedBase();
    helper();
  }
  private static void helper() {
    new C();
  }
}

C:\devel\scratch\annotation>ajc -1.5 AnnotatedCtor.aj
C:\devel\scratch\annotation\AnnotatedCtor.aj:19 [warning] I new call
new AnnotatedBase();
^^^^^^^^^^^^^^^^^^^^
        constructor-call(void AnnotatedBase.<init>())
        see also: C:\devel\scratch\annotation\AnnotatedCtor.aj:11::0
C:\devel\scratch\annotation\AnnotatedCtor.aj:19 [warning] I new call,
indirectly

new AnnotatedBase();
^^^^^^^^^^^^^^^^^^^^
        constructor-call(void AnnotatedBase.<init>())
        see also: C:\devel\scratch\annotation\AnnotatedCtor.aj:12::0
C:\devel\scratch\annotation\AnnotatedCtor.aj:23 [warning] I new call on ctor
new C();
^^^^^^^^
        constructor-call(void C.<init>())
        see also: C:\devel\scratch\annotation\AnnotatedCtor.aj:13::0

3 warnings

C:\devel\scratch\annotation>java AnnotatedCtor
I new exec with @target AnnotatedBase@1971afc

I'd expect the @target form in the advice to match the construction of C in
this example, but it appears that the rule is based on whether the
annotation is on the most derived class and not whether the type has an
annotation on one of its runtime types.

Also, I believe that the call to construct C should produce a warning of "I
new call, indirectly", since C is a subtype of AnnotatedBase and the latter
matches (@I *).

-----Original Message-----
From: aspectj-users-bounces@xxxxxxxxxxx
[mailto:aspectj-users-bounces@xxxxxxxxxxx] On Behalf Of Dean Wampler
Sent: Thursday, April 20, 2006 1:18 PM
To: wes@xxxxxxxxxxxxxx; aspectj-users@xxxxxxxxxxx
Subject: Re: [aspectj-users] AW: Pointcut on a constructor
withacustom@Annotation

Unless I'm mistaken,

call( @MyAnnotation * *.new(..) )

is okay; it matches constructors annotated with @MyAnnotation, while

call( * (@MyAnnotation *).new(..) )

Matches constructors in classes where the class has the annotation.

dean

On 4/20/06, Wes <wes@xxxxxxxxxxxxxx> wrote:
>
> That's the right idea, but I believe
>
>   call( @MyAnnotation * *.new(..) )
>
> results in a syntax error since "@MyAnnotation * *" is not a typepattern.
>
>
> Wes
>
>
>
>
> ------------Original Message------------
> From: Scott <aspectj-users@xxxxxxxxxxx>
> To: aspectj-users@xxxxxxxxxxx
>
> Date: Thu, Apr-20-2006 1:03 PM
> Subject: Re: [aspectj-users] AW: Pointcut on a constructor with
> acustom@AnnotationMoritz,
>
> Have you tried it this way yet?
>
> @AfterReturning(pointcut = "call( @MyAnnotation * *.new(..) )", returning
=
> "obj")
> public void beforeConstructor(Object obj) {
>    System.out.println(obj);
> }
>
> -Scott
>
> =========================================
>
>
> On 4/20/06, Moritz Post <moritzpost@xxxxxx> wrote:
> > Hello Ron
> >
> > > Please take a look at this FAQ entry:
> > >
> http://www.eclipse.org/aspectj/doc/released/faq.html#q:adviseconstructors
> > >
> > > Basically, you can't use @target for the call to a constructor: there
> > > isn't
> > > one. You could use @target for execution of the constructor or you
could
> > > bind the returned object with after returning advice and then use
> > > reflection
> > > to test for an annotation on the object.
> >
> > If I was only concerned with the constructor, I could use an
> @AfterReturning
> > advise like the following to get the newly created object:
> >
> > @AfterReturning(pointcut = "call(* .new(..))", returning = "obj")
> > public void beforeConstructor(Object obj) {
> >     System.out.println (obj);
> > }
> >
> > This return the new object in the "obj" Object.
> >
> > But my problem is the combination of the above with an @Annotation. The
> > pointcut should only kick in if the class has a specific annotation.
> >
> > > Hallo Again
> > >
> > > Sorry, I hit send accidentally. :(
> > >
> > > > Hallo Mailingliste
> > > >
> > > > I am struggling to create a proper pointcut on a constructor. I want
> to
> > > > catch all creations of an object which is annotated with a custom
> > > > annotation. Like:
> > > >
> > > > @MyAnnotation
> > > > public class TheClass {
> > > >
> > > >   public TheClass {
> > > >   }
> > > >
> > > > }
> > > >
> > > > So whenever a classlass is instantiated I want to get the instance
of
> > > that
> > > class (having the MyAnnotation annotation).
> > > > Therefore I developed the following Pointcut:
> > >
> > > So I continue here with the mentioned pointcut:
> > >
> > > @AfterReturning(pointcut = "call(* .new(..)) &&
@target(MyAnnotation)",
> > > returning = "obj")
> > >   public void objectCreation() {
> > >   }
> > >
> > > The problem here is, that the combination of the call(* .new(..)) and
> the
> > > @target(MyAnnotation) does not work. I can either remove the @target
and
> > > it
> > > works fine or I can remove the call(..) and let the @target be the
key.
> > > But
> > > together those two do not work.
> > >
> > > Am I doing something completely wrong? Or is there another suggested
way
> > > to
> > > intercept a newly created object?
> > >
> > > Any help is appreciated
> > >
> > > Regards
> > > Moritz Post
> >
> > Regards
> > Moritz Post
> >
> > _______________________________________________
> > aspectj-users mailing list
> > aspectj-users@xxxxxxxxxxx
> > https://dev.eclipse.org/mailman/listinfo/aspectj-users
> >
>
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>
>
>


--
Dean Wampler
http://www.aspectprogramming.com
http://www.newaspects.com
http://www.contract4j.org
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users




Back to the top