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

Thanks Andy,
It works great :)

On 4/26/10, Andy Clement <andrew.clement@xxxxxxxxx> wrote:
Hi,

inline answers:


On 26 April 2010 00:43, Mohammad Norouzi <mnrz57@xxxxxxxxx> wrote:
> 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);


If you do need to bind the annotation, you should use @annotation() -
yes there is some cost due to retrieval of it, but it should be the
same cost as if you accessed it through thisJoinPointStaticPart (and
you'd get it through that by accessing the method and retrieving it
via reflection).  I only wanted you to avoid @annotation if you were
just matching and not binding because that is usually unnecessary
overhead.  So the best thing to do above is add the @annotation
clause:

          pointcut eventMethods(Object obj,Object iparam,Event e) :
              within(@Observable com..*)
             && @annotation(e)

             && execution(@Event * *.*(..))
              && target(obj)
              && args(iparam);


See http://eclipse.org/aspectj/doc/released/README-167.html (the
bottom section on annotation binding) for some comparisons on recent
improvements in this area.  There is an optimized syntax for some
kinds of annotation value that avoids any reflection cost but maybe
get your code working first before changing it to exploit that.  If
you are interested in learning more,
http://eclipse.org/aspectj/doc/released/README-161.html - see the
section on 'optimized syntax for annotation value binding'.


> 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


//1 - use the binding code I showed above
//2 -  ((ObservableInterface)thisJoinPoint.getThis()).eventDispatcher.dispatch(e);
  or bind 'this' in the pointcut and access the eventdispatcher on it.


Andy


>
> 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
>
>
> _______________________________________________
> 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


Back to the top