[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] Bizarre behavior with args pointcut

                                   Hi!

  I ran into bizarre behavior. A pointcut misses a method depending whether or 
not I use args to collect context.

  I made a simplified example about this:

<-- clip -->

public class Account {

  public static void main(String[] args) {
    Account a1 = new Account();
    Account a2 = new Account();
    a1.credit(100);
    a2.credit(50);
    a1.debit(10);
    a1.transfer(a2, 30);
  }

   public void credit(double amount) {}

   public boolean debit(double amount) {
        return true;
   }

   public boolean transfer(Account target, double amount) {
      if(this.debit(amount)) {
         target.credit(amount);
         return true;
      }
      return false;
   }


}

aspect ContextCollectingAspect {

   pointcut changeOperations(Account a, double d) :
      execution(* Account.*(..,double,..))
      && this(a)
      && args(d);

  // this is the same as above, except it doesn't collect any context 
  before() : execution(* Account.*(..,double,..)) {
      System.out.println(">>> Going into: " + thisJoinPointStaticPart);
   }

   before(Account a, double d): changeOperations(a, d) {
      System.out.println(">>> Checking preconditions for " + a +
         " in join point " + thisJoinPointStaticPart);
   }
}

</-- clip -->

  Now I would assume that both pieces of before advice in the above aspect 
match the same join points as the only difference is that the first collects 
context whereas the latter does not. However, the program prints:

<-- clip -->

>>> Going into: execution(void Account.credit(double))
>>> Checking preconditions for Account@1729854 in join point execution(void 
Account.credit(double))
>>> Going into: execution(void Account.credit(double))
>>> Checking preconditions for Account@6eb38a in join point execution(void 
Account.credit(double))
>>> Going into: execution(boolean Account.debit(double))
>>> Checking preconditions for Account@1729854 in join point execution(boolean 
Account.debit(double))
>>> Going into: execution(boolean Account.transfer(Account, double))
>>> Going into: execution(boolean Account.debit(double))
>>> Checking preconditions for Account@1729854 in join point execution(boolean 
Account.debit(double))
>>> Going into: execution(void Account.credit(double))
>>> Checking preconditions for Account@6eb38a in join point execution(void 
Account.credit(double))

</-- clip -->

  As you can see, the context collecting pointcut misses the transfer 
execution join point. 

  After a bit of thinking I changed the context collection a little:

      && args(..,d,..);

  Resulting in:
Account.java:34 uses more than one .. in args (compiler limitation)
1 error

  So I changed it into:

      && args(..,d);

  and it works fine. It also seems to work even if the double is not the last 
argument, even though it looks to me as if it shouldn't.

  Is there some logic to having to use the form args(..,d) when collecting 
context? Why does the form args(d) not work here?
	

-- 
Antti Karanta <Antti.Karanta@xxxxxxxxxxxxxx>
Konsultti
FCS Partners Oyj
ph +358407634648
http://www.fcspartners.fi