Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: Couple other questions - Re: [aspectj-users] How do i apply a pointcut to only an object which implements an interface or is of type X.class or subclass

Thanks for the detailed response. Are there any statistics/performance measurements available for AspectJ???

Also  I "think" i now am understanding the difference between call and execution.

I think another way to think about it is with the code generated??

call() generates code in the context of the call while execution generates code in the target of the call???

call() generates code in each place the adviced code is called where execution only changes the original target method, or constructor, e.g. the caller does not generate code..


Example call() generated code. Each time this object is created the code will be intected into the calling codes class. This can happen N times.

        Map map = new HashMap(10);
        System.out.println(map);
        JoinPoint joinpoint = Factory.makeJP(ajc$tjp_0, null, null);
        Object aobj[] = new Object[1];
        aobj[0] = joinpoint;
        MockDeliveryChannel mockdeliverychannel = (MockDeliveryChannel)JBIInterceptorAspect.aspectOf().ajc$around$com_sun_esb_console_jbi_aspects_example_JBIInterceptorAspect$3$aafa08b1(new AjcClosure1(aobj), joinpoint);
...

Example execute() generated code This method looks same to all callers. This happens only once.

    public MessageExchange accept()
        throws MessagingException
    {
        JoinPoint joinpoint = Factory.makeJP(ajc$tjp_0, this, this);
        Object aobj[] = new Object[2];
        aobj[0] = this;
        aobj[1] = joinpoint;
        return (MessageExchange)JBIInterceptorAspect.aspectOf().ajc$around$com_sun_esb_console_jbi_aspects_example_JBIInterceptorAspect$12$e77868db(this, new AjcClosure1(aobj), joinpoint);
    }


Andy Clement wrote:
Hi,

public pointcut PT_new() : within(com.foo.BarInterface+) && // not sure why this doesn't work?? call(*.new(..));

this doesn't work because you are using within() to limit the set of join points you might match to those in BarInterface or a subtype of BarInterface. And then from that subset you are saying you want any constructor call. Here is a piece of code that will match your pointcut, and I don't think it is what you want:

-- Code.java --
package com.foo;

interface BarInterface { } class Impl implements BarInterface { public void m() { new String("hello"); // MATCHES } }
aspect X{ public pointcut PT_new() : within(com.foo.BarInterface+) && call(*.new(..)); before():PT_new() {} }
-- end of Code.java --

ajc -showWeaveInfo Code.java
Join point 'constructor-call(void java.lang.String.<init>(java.lang.String))' in Type 'com.foo.Impl' (Code.java:9) advised by before advice from 'com.foo.X' (Code.java:18)

the call to new String() is a constructor call from within BarInterface+

For call and execution.  Think about program flow.  As a program is executing we are running some bit of code... we hit a line that wants to call a method.  The call joinpoint occurs right there and then.  The method is then invoked and the execution joinpoint occurs.  The call joinpoint occurs in the context ('within') of the calling location.  The execution joinpoint occurs in the context ('within') the code defining the executing method.  When all joinpoints in a system are exposed to the weaver, it doesn't make that much difference.  However, when you only have access to part of the system for weaving, it can make a big difference.  In my example above, I can weave the call() join point that is 'new String()' because I am weaving the code making the call.  I could not easily weave the execution() join point for it as that would mean I'd have to weave the constructor in the class java.lang.String in rt.jar.

Using execution() when you can is a little more efficient, since you might have a library call that is called from 50 places in the system.  You either weave the one place where it is defined (using execution()) or the 50 separate calls to it (using call()).

Weaving constructors complicates the situation - especially when you use around and try to return something different.  I would say do not try and understand call and execution when thinking about constructors, just think about methods initially.  Once you understand that, we can add constructors into the mix.  I'm sure someone else on the list who has experience weaving constructors will comment further.

Andy.

2008/12/3 Jason Weinstein <Jason.Weinstein@xxxxxxx>
Cool thanks, but NOTE that DIDN'T work for me either. I did find something that did thanks to the "+" you pointed out.

NO
  public pointcut PT_new() :

      within(com.foo.BarInterface+) && // not sure why this doesn't work??
      call(*.new(..));
    
YES
    public pointcut PT_new() :

        call(public com.foo.BarInterface+.new(..));


TWO MORE QUESTIONS.

QUESTION 1

Can someone explain the difference in behavior here between call and execute?? I'm not sure i'm really caught on to the difference in these two.

    public pointcut PT_new() :

        call(public com.foo.BarInterface+.new(..));

    Object around()
                  throws Exception :
        PT_new() {
        return null;
    }


BarInterface bar = new BarInterfaceImpl();
Here bar == null


    public pointcut PT_new() :

        execute(public com.foo.BarInterface+.new(..));

    Object around()
                  throws Exception :
        PT_new() {
        return null;
    }


BarInterface bar = new BarInterfaceImpl();
Here bar != null, rather its a new BarInterfaceImpl instance


QUESTION 2

What happens when a the original method does not throw an Exception but the advice throws an Exception?? Does the "throws Exception" get woven into the original Constructor (or Method)? I tested it and i guess you would just get an unhandled exception. This seems real bad and i guess is something to watch out for??

e.g.
public class BarInterfaceImpl implements BarInterface {
    public BarInterfaceImpl() {} // does not throw Exception
}


    public pointcut PT_new() :

        call(public com.foo.BarInterface+.new(..));

    Object around()
                  throws Exception :
        PT_new() {
        throw Exception();
    }





Andrew Eisenberg wrote:
  public pointcut PT_new() :

      within(com.foo.BarInterface) &&
      call(*.new(..));

    
Try this instead:

   public pointcut PT_new() :
       within(com.foo.BarInterface+) &&
       call(*.new(..));

'+' means to include subclasses.
_______________________________________________
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

Back to the top