[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] How to determine whether a nested class constructor is being called

Thanks for the reply Eric.

I would agree that the behaviour does not seem to make sense, can anyone confirm our suspicion as to whether this really is a bug?

Thank you

Piers


Eric Bodden wrote:
I think that the current behavior does not make much sense. Usually,
the additional parameter holds the outer instance of the inner class.
It should never be null, and I am not sure why null ends up being
bound in the aspect in your case. I think that's a bug.

Either AspectJ should correctly bind the outer instance, or it should
not expose this implicit argument at all (which is probably what one
actually wants).

Just my two cents,
Eric

2008/11/15 Piers Powlesland <piers@xxxxxxxxxxxxxxxxxxxxxxxxx>:
Hi

I am attempting to write an aspect that checks for null arguments passed to
any constructors defined in our project, the problem i am having is that
calls to constructors of inner classes get passed a *secret* parameter which
evaluates to null. I cannot seem to figure out a way to determine whether
the constructor called belongs to a nested class and therefore cannot avoid
these special cases.

Here is some example code.

First the aspect that i have created

||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

package com.historicalengineering.wwii.aspect.test;

import java.lang.IllegalArgumentException;

public aspect EnforceContractAspect
{

       pointcut allMethodCallsWithParameters() :
               call(* com.historicalengineering..*(*,..));

       pointcut allConstructorCallsWithParameters() :
               call(com.historicalengineering..new(*,..)) ||
               call(private com.historicalengineering..new(*,..)) ||
               call(protected com.historicalengineering..new(*,..)) ||
               call(public com.historicalengineering..new(*,..));

       /*
        * Select all calls to any methods or constructors defined within
        * com.historicalengineering taking one or more parameters
        */
       pointcut allCallsWithParameters() :
               allConstructorCallsWithParameters() ||
               allMethodCallsWithParameters();


before() : allCallsWithParameters() {

               Object[] args = thisJoinPoint.getArgs();

               for(int i = 0; i < args.length; i++)
               {
                       if(args[i] == null)
                       {

                               throw new IllegalArgumentException(

 thisJoinPointStaticPart.getSignature()
                                               +" passed null parameter at
position "+(i+1)
                                               +" of "+args.length);
                       }
               }

       }
}

||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

Second the test class

||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

package com.historicalengineering.wwii.aspect.test;

public class A
{

       public static void main(String[] args)
       {
               //A a = new A();
               //InnerStatic i = new InnerStatic();
               //a.foo();
               //a.bar();

       }

       protected void foo()
       {
               InnerStatic inner = new InnerStatic();
       }

       protected void bar()
       {
               Inner inner = new Inner();
       }

       static class InnerStatic
       {
               private InnerStatic()
               {
               }
       }

       class Inner
        {
               private Inner()
               {
               }
       }

}


||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

Third some output

||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||


Output when uncommenting the line: A a = new A();

-None because this constructor really doesn't take any parameters.



Output when uncommenting the line:      InnerStatic i = new InnerStatic();

Exception in thread "main" java.lang.IllegalArgumentException:
com.historicalengineering.wwii.aspect.test.A.InnerStatic(A.InnerStatic)
passed null parameter at position 1 of 1
       at
com.historicalengineering.wwii.aspect.test.EnforceContractAspect.ajc$before$com_historicalengineering_wwii_aspect_test_EnforceContractAspect$1$f789a125(EnforceContractAspect.aj:45)
       at com.historicalengineering.wwii.aspect.test.A.main(A.java:9)

- As you can see from the trace the inner static constructor was passed an
"A.InnerStatic"  type which has evaluated to null.



Output when uncommenting the lines:     A a = new A();  &       a.foo();

Exception in thread "main" java.lang.IllegalArgumentException:
com.historicalengineering.wwii.aspect.test.A.InnerStatic(A.InnerStatic)
passed null parameter at position 1 of 1
       at
com.historicalengineering.wwii.aspect.test.EnforceContractAspect.ajc$before$com_historicalengineering_wwii_aspect_test_EnforceContractAspect$1$f789a125(EnforceContractAspect.aj:40)
       at com.historicalengineering.wwii.aspect.test.A.foo(A.java:17)
       at com.historicalengineering.wwii.aspect.test.A.main(A.java:10)

- Again the null "A.InnerStatic" type has been passed to the constructor.



Output when uncommenting the lines:     A a = new A();  &       a.bar();

Exception in thread "main" java.lang.IllegalArgumentException:
com.historicalengineering.wwii.aspect.test.A.Inner(A, A.Inner) passed null
parameter at position 2 of 2
       at
com.historicalengineering.wwii.aspect.test.EnforceContractAspect.ajc$before$com_historicalengineering_wwii_aspect_test_EnforceContractAspect$1$f789a125(EnforceContractAspect.aj:40)
       at com.historicalengineering.wwii.aspect.test.A.bar(A.java:22)
       at com.historicalengineering.wwii.aspect.test.A.main(A.java:11)

-In the case of the non static nested class it is passed 2 hidden parameters
the enclosing class "A" which does not evaluate to null and again the
infuriating "A.Inner" class which is null.


Your thoughts and help would be very much appreciated.

Thank you

Piers

_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users