Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] private calls and within inner classes



Bruno,

I think I know what the problem is but the solution is not straightforward.
In order to call private methods on a class in the same scope there is no
magic. Instead the compiler generates accessor methods (with default
visibility) which in turn call the private methods. AspectJ is attaching
advice to the accessor methods which make the actual private method call
hence the results you see. I believe there have been bugs reported in this
area before and you may like to take a look at Bugzilla.

Matthew Webster
AOSD Project
Java Technology Centre, MP146
IBM Hursley Park, Winchester,  SO21 2JN, England
Telephone: +44 196 2816139 (external) 246139 (internal)
Email: Matthew Webster/UK/IBM @ IBMGB, matthew_webster@xxxxxxxxxx
http://w3.hursley.ibm.com/~websterm/

Bruno Harbulot <bruno.harbulot@xxxxxxxxxxxx>@eclipse.org on 08/03/2005
16:17:16

Please respond to aspectj-users@xxxxxxxxxxx

Sent by:    aspectj-users-admin@xxxxxxxxxxx


To:    aspectj-users@xxxxxxxxxxx
cc:
Subject:    Re: [aspectj-users] private calls and within inner classes


Hello Matthew,


Indeed, my example was a bit confusing. As you suggested, "declare
warning ..." and showWeaveInfo produce clearer results.
I think there might be a bug: the piece of advice for the private call
appears to be woven at the line of the called method itself.



On the shorter example pasted at the end of this message, the output (of
ajc 1.2.1) is:


Type 'Test$InnerB' (Test.aj:14) advised by before advice from
'TestAspect' (Test.aj:44)

Type 'Test$InnerB' (Test.aj:14) advised by before advice from
'TestAspect' (Test.aj:41)

Type 'Test$InnerA' (Test.aj:3) advised by before advice from
'TestAspect' (Test.aj:47)

Test.aj:3 [warning] Call to runPrivate(..)
private static void runPrivate(int a) {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         method-call(void Test$InnerA.runPrivate(int))
         see also: Test.aj:38
Test.aj:14 [warning] Call to runPublic(..) from run() in inner class B
InnerA.runPublic(1);
^^^^^^^^^^^^^^^^^^^
         method-call(void Test$InnerA.runPublic(int))
         see also: Test.aj:32
Test.aj:14 [warning] Call to runPublic(..)
InnerA.runPublic(1);
^^^^^^^^^^^^^^^^^^^
         method-call(void Test$InnerA.runPublic(int))
         see also: Test.aj:31




This seems to mean that the result of the conjunction between
"withincode" and "call" makes the use of "withincode" depend on the
visibility of the method(s) selected by "call".

Also, "call" used alone on the private method is woven at line 3 in
Test$InnerA (i.e. on the called method), whereas it is woven at line 14
(on the call itself, as expected) for the public method.

Is there some kind of inling taking place before the weaving? If so, I'm
even surprised that the call to the private method is advised at all.


Regards,

Bruno.






public class Test {
     public static class InnerA {
         private static void runPrivate(int a) {
             System.out.println("InnerA private: " + a);
         }
         public static void runPublic(int a) {
             System.out.println("InnerA public: " + a);
         }
     }

     public static class InnerB {
         public void run() {
             InnerA.runPrivate(1);
             InnerA.runPublic(1);
         }
     }

     public static void main(String[] args) {
         InnerB innerb = new InnerB();
         innerb.run();
     }
}


privileged aspect TestAspect {
     pointcut callPrivate(): call(void Test.InnerA.runPrivate(..)) ;
     pointcut callPublic(): call(void Test.InnerA.runPublic(..)) ;
     pointcut withinInnerRun(): withincode(* Test.InnerB.run()) ;

     /* These two warning appear correctly on the call. */
     declare warning: callPublic() : "Call to runPublic(..)";
     declare warning: callPublic() && withinInnerRun() : "Call to
runPublic(..) from run() in inner class B";

     /*
      * Only the warning that is restricted with "withincode" appears,
      * and it appears on the called method itself.
      */
     declare warning: callPrivate() : "Call to runPrivate(..)";
     declare warning: callPrivate() && withinInnerRun() : "Call to
runPrivate(..) from run() in inner class B";

     before(): callPublic() {
         System.err.println("Call to runPublic(..)");
     }
     before(): callPublic() && withinInnerRun() {
         System.err.println("Call to runPublic(..) from run() in inner
class B");
     }
     before(): callPrivate() {
         System.err.println("Call to runPrivate(..)");
     }
     before(): callPrivate() && withinInnerRun() {
         System.err
                 .println("Call to runPrivate(..) from run() in inner
class B");
     }
}




Matthew Webster wrote:
>
> Bruno,
>
> You might like to use "declare warning ..." and/or -showWeaveInfo to
> determine whether a problem lies in AspectJ or AJDT/Visualiser.
>
> Matthew Webster
> AOSD Project
> Java Technology Centre, MP146
> IBM Hursley Park, Winchester,  SO21 2JN, England
> Telephone: +44 196 2816139 (external) 246139 (internal)
> Email: Matthew Webster/UK/IBM @ IBMGB, matthew_webster@xxxxxxxxxx
> http://w3.hursley.ibm.com/~websterm/


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




Back to the top