Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] How to rewrite a class with AspectJ

Thank you Andy,
I got it. As you stated @annotation is for dynamic matching and this has performance issues, can you tell me how can I access the annotation on the method in a static way? I assumed that we can access it through thisJoinPointStaticPart but I couldn't find any method for that.

        pointcut eventMethods(Object obj,Object iparam) :
            within(@Observable com..*)
            && execution(@Event * *.*(..))
            && target(obj)
            && args(iparam);

Apart from that I've got another problem. I want to add a field with an annotation on it inside all classes which are marked with @Observable. I had a look at OvserverProtocol example and some others in Internet but they don't meet my requirements. So I have this code:

    interface ObservableInterface {};

    declare parents: @Observable com..* implements ObservableInterface;

    @EJB
    private EventDispatcher ObservableInterface.eventDispatcher;


now in my advice how can I call dispatch(Event) method of that observable class:
 
        after(Object obj,Object iparam) : eventMethods(obj,iparam) {
            System.out.println("thisJoinPoint:"+thisJoinPointStaticPart.toLongString());
            System.out.println("thisJoinPointSig:"+thisJoinPointStaticPart.getSignature().toLongString());
            System.out.println("input param: "+iparam);
            System.out.println("target objet: "+obj);
            com.foo.listener.Event e = new com.foo.listener.Event();
            e.setName("don't know"); //1
            e.setParam(iparam);
            e.setSource(obj.getClass().getName());
           
            //eventDispatcher.dispatch(e); //2
           
        }

//1   how to access @Event to extract event name from it
//2   how to call dispatch(Event) method

thanks

On Sun, Apr 25, 2010 at 10:17 PM, Andy Clement <andrew.clement@xxxxxxxxx> wrote:
@annotation can match dynamically.  dynamic matching throughtout
AspectJ means we couldn't check what you asked statically (at compile
time) so had to insert some code to check it at runtime.  Static
matching leaves no runtime overhead.

> eventMethods(Event e,Object obj,Object iparam) :
> ...
> && @args(e)

That isn't what you want.  That would match where the join point takes
an argument and that the type of that argument has the Event
annotation.  Eg. this method would match because SomeType is marked
@Event:

public void foo(SomeType obj)

where:

@Event
class SomeType {}

What you want is:

eventMethods(Event e, Object obj, Object iparam):
&& @annotation(e)

because '@annotation' is being matched against the subject of the
joinpoint and for method execution, the subject is the method itself.

Andy

On 25 April 2010 10:32, Mohammad Norouzi <mnrz57@xxxxxxxxx> wrote:
> Hi Andy,
> Thanks... what does 'dynamic match' mean?
> I finally end up with a pointcut that match my desired points but the thing
> is that when I want to pass the Event annotation the pointcut doesn't work
> anymore
>
> To pass the annotation I changed the signature to
>
> eventMethods(Event e,Object obj,Object iparam) :
> ...
> && @args(e)
>
> is this correct?
>
> On 4/25/10, Andy Clement <andrew.clement@xxxxxxxxx> wrote:
>>
>> I've only looked at it quickly, but first thing I spot is you haven't
>> used '..' in the within clause.
>>
>> within(@Observable com.*)
>>
>> will match packages com.Foo, com.Bar, it will not match
>> com.somewhere.Foo or com.somewhere.else.Bar.  I doubt that is what you
>> want so change it to double dot.
>>
>> within(@Observable com..*)
>>
>> Also I see you using @annotation(Event) - did you really need a
>> dynamic match on that?  If you don't you could just statically match
>> it by remove the @annotation clause and putting the annotation in the
>> execution pointcut:
>>
>> execution(@Event * *.*(..))
>>
>>
>> Andy
>>
>>
>> On 25 April 2010 02:17, Mohammad Norouzi <mnrz57@xxxxxxxxx> wrote:
>> > Hi Simone,
>> > Can you please tell me what's wrong with this pointcut. I want all the
>> > methods which is in a type annotated with @Observable and the method
>> > itself
>> > annotated with @Event
>> >
>> > @Observable
>> > public class O1 {
>> >
>> >    @Event(value = {"EVENT1","EVENT2"})
>> >    public void method1(String str) {
>> >
>> >    }
>> > }
>> >
>> > package com.foo.aspect;
>> >
>> > import com.foo.annotation.*;
>> >
>> > public aspect EventDispatcherAspect {
>> >
>> >         pointcut eventMethods(Object obj,Object iparam) :
>> >             within(@Observable com.*)
>> >         &&    execution(* *.*(..))
>> >         && @annotation(Event)
>> >         && args(iparam)
>> >         && target(obj);
>> >
>> >         after(Object obj,Object iparam) returning:
>> > eventMethods(obj,iparam)
>> > {
>> >
>> >
>> > System.out.println("thisJoinPoint:"+thisJoinPointStaticPart.toLongString());
>> >
>> >
>> > System.out.println("thisJoinPointSig:"+thisJoinPointStaticPart.getSignature().toLongString());
>> >             //System.out.println("Events: "+e.value());
>> >
>> >         }
>> > }
>> >
>> >
>> > Regards,
>> > Mohammad
>> > --------------------------
>> >
>> > On Wed, Apr 21, 2010 at 4:51 PM, Simone Gianni <simoneg@xxxxxxxxxx>
>> > wrote:
>> >>
>> >> Hi Mohammad,
>> >> nope, unfortunately AspectJ is not able to declare fields
>> >> "dynamically",
>> >> moreover private fields injected by AspectJ have a number of
>> >> limitations
>> >> that are being solved (they have mangled names).
>> >>
>> >> What you can do however is :
>> >> - Declare an interface WithObserverABC
>> >> - Use an ITD to place a privare field on that interface
>> >> - Inject that interface on all classes that have @Observable
>> >> - Write the aspect that calls the observer method when an @Observable
>> >> method is executed.
>> >>
>> >> public aspect InjectObserverABC {
>> >>   public interface WithObserverABC {}
>> >>
>> >>   // this could be private, except for name mangling, depends on
>> >> AspectJ
>> >> version
>> >>   public ObserverAbc WithObserverABC.abcObserver = new
>> >> ObserverABCImpl();
>> >>
>> >>   // you could narrow this
>> >>   declare parents : hasmethod(@Observable *(..)) implements
>> >> WithObserverABC;
>> >>
>> >>   before(WithObserverABC instance) : execution(@Observable *
>> >> WithObserverABC+.*(..)) && this(instance) {
>> >>     instance.abcObserver.
>> >> notifyObserver();
>> >>   }
>> >> }
>> >>
>> >> I'm not sure about the syntax (I wrote it here in this email, and i
>> >> need
>> >> compiler support when writing pointcuts :) ), but you should get the
>> >> idea.
>> >> Eventually you can try to play with generics/abstract aspects to make
>> >> it
>> >> easier to inject new observers, but I cannot think of a way of doing
>> >> this
>> >> completely automatically (apart from using APT to parse classes with
>> >> @Observer and generate dynamically aop.xml to instantiate concrete
>> >> aspects
>> >> ... but that's another story :) )
>> >>
>> >> Hope this helps,
>> >> Simone
>> >>
>> >> 2010/4/20 Mohammad Norouzi <mnrz57@xxxxxxxxx>
>> >>>
>> >>> Hi Simone,
>> >>> >>if I understand correctly, when a method annotated with @Observable
>> >>> >> is
>> >>> >> executed, you want to see if there are fields in that class with an
>> >>> >> instance
>> >>> >> of an observer, and call a method on the observer.<<
>> >>> Actually, when a method is annotated with @Observable (before
>> >>> executing
>> >>> and at the time of compiling codes) I want to add (not see) those
>> >>> interfaces
>> >>> that annotated with @Observer, as  private fields in the observable
>> >>> and I
>> >>> want to add them because both observer and observable are EJB session
>> >>> beans
>> >>> so the application server will take the burden of instantiating those
>> >>> observers using its injection technique
>> >>>
>> >>> What I need is something like this:
>> >>> for(MyObserver o : observers){
>> >>>    declare a private field with a name in this instance of observable
>> >>> class
>> >>> }
>> >>>
>> >>>
>> >>> On Mon, Apr 19, 2010 at 2:22 PM, Simone Gianni <simoneg@xxxxxxxxxx>
>> >>> wrote:
>> >>>>
>> >>>> Hi Mohammad,
>> >>>> if I understand correctly, when a method annotated with @Observable
>> >>>> is
>> >>>> executed, you want to see if there are fields in that class with an
>> >>>> instance
>> >>>> of an observer, and call a method on the observer.
>> >>>>
>> >>>> You can use AspectJ to execute an advice before/after/around the
>> >>>> execution of @Obervable methods, and use thisJoinPoint or the this()
>> >>>> construct to find the instance of the method.
>> >>>>
>> >>>> Once you are there, you must use plain java reflection, and not
>> >>>> AspectJ,
>> >>>> to find fields in that class that contains an observer and invoke
>> >>>> observer
>> >>>> methods.
>> >>>>
>> >>>> To add @EJB annotation to all fields of type X where X is annotated
>> >>>> with
>> >>>> @Observer, you can use declare @class and write a type pattern that
>> >>>> uses
>> >>>> @Observer annotation. If @Observer annotation is placed on methods,
>> >>>> you can
>> >>>> use hasmethod() to find classes that has such methods, but beware
>> >>>> cause
>> >>>> hasmethod is somewhat experimental.
>> >>>>
>> >>>> Hope this helps,
>> >>>> Simone
>> >>>>
>> >>>> 2010/4/19 is_maximum <mnrz57@xxxxxxxxx>
>> >>>>>
>> >>>>> Thanks Simone, yes this is exactly what I want... but another
>> >>>>> question
>> >>>>> is
>> >>>>> that this is used using 'declare' and as far as I know declare is
>> >>>>> placed in
>> >>>>> aspect definition. How can I place it in a for-loop.
>> >>>>>
>> >>>>> Let me tell you the scenario may be I am in wrong way...
>> >>>>>
>> >>>>> I am trying to implement an observer pattern in EJB 3.0. I saw many
>> >>>>> implementation using aspectJ but mine is a little different. The
>> >>>>> difference
>> >>>>> is that I want to inject observer into observable...
>> >>>>>
>> >>>>> Because session beans are managed object and in my case both
>> >>>>> observer
>> >>>>> and
>> >>>>> observable supposed to be session beans I want application server
>> >>>>> injects
>> >>>>> observer session beans in observable SB and then call observer
>> >>>>> methods
>> >>>>>
>> >>>>> These observer and observable methods will be annotated by the
>> >>>>> developer
>> >>>>> with say @Observer and @Observable
>> >>>>>
>> >>>>> What I wanted was to look for @Observer methods and find their
>> >>>>> interface and
>> >>>>> put them like this:
>> >>>>>
>> >>>>> @EJB
>> >>>>> private ObserverInterface1 observer1
>> >>>>>
>> >>>>> than each time the determined method is called I can call
>> >>>>> observer1.notifyObserver() method
>> >>>>>
>> >>>>> Can you please help me on this?
>> >>>>>
>> >>>>>
>> >>>>>
>> >>>>>
>> >>>>> Simone Gianni-2 wrote:
>> >>>>> >
>> >>>>> > Hi  Mohammad,
>> >>>>> > maybe you are loooking for the declare annotation statement?
>> >>>>> >
>> >>>>> >
>> >>>>> > http://www.eclipse.org/aspectj/doc/next/adk15notebook/annotations-declare.html
>> >>>>> >
>> >>>>> > Simone
>> >>>>> >
>> >>>>> >
>> >>>>>
>> >>>>>
>> >>>>> -----
>> >>>>> --
>> >>>>> Regards
>> >>>>>
>> >>>>> Mohammad Norouzi
>> >>>>>
>> >>>>> Help each other to reach the future faster
>> >>>>>
>> >>>>> http://pixelshot.wordpress.com Pixelshot Photoblog
>> >>>>>
>> >>>>> http://brainable.blogspot.com Brainable Blog
>> >>>>>
>> >>>>>
>> >>>>> --
>> >>>>> View this message in context:
>> >>>>>
>> >>>>> http://old.nabble.com/How-to-rewrite-a-class-with-AspectJ-tp28280867p28287273.html
>> >>>>> Sent from the AspectJ - users mailing list archive at Nabble.com.
>> >>>>>
>> >>>>> _______________________________________________
>> >>>>> 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
>> >>>
>> >>
>> >>
>> >> _______________________________________________
>> >> 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
>
>
>
> --
> Regards,
> Mohammad
> --------------------------
> Sun Certified Web Developer
> ExpertsExchange Certified, Master:
> http://www.experts-exchange.com/M_1938796.html
> Have a look at some pictures @ http://pixelshot.wordpress.com/
> Do you like to read, see http://brainable.blogspot.com/
> For the Persians see http://fekre-motefavet.blogspot.com/
> English
> Forum:http://n2.nabble.com/English-Phrase-Finder-For-Persians-f3274251.html
>
>
> _______________________________________________
> 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


Back to the top