How to exclude an anonymous inner method from a pointcut?

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

How to exclude an anonymous inner method from a pointcut?

Ian Worthington
I have an AspectJ trace routine set up to log method entry and exit
conditions using the following pointcuts:

     public aspect Trace {
         pointcut anyMethodExecuted():       execution (*
biz.ianw.lanchecker.*.*(..)) && !within(Trace); // && !within(
is(AnonymousType) );
         pointcut anyConstructorExecuted():  execution
(biz.ianw.lanchecker.*.new(..)) && !within(Trace);


In my email class I have a method which calls the setDebugOut method to
redirect the debug output to a LogOutputStream:

     final private static  Logger log =
LoggerFactory.getLogger(MailMail.class);
     ...
     LogOutputStream losStdOut = new LogOutputStream() {
         @Override
         protected void processLine(String line, int level) {
             log.debug(line);
         }
     };

     public void sendPlainHtmlMessage(...) {
         Session session = javaMailSender.getSession();
         PrintStream printStreamLOS = new PrintStream(losStdOut);
         session.setDebugOut(printStreamLOS);
         ...

This works fine, except that the Trace class pointcut intercepts the
call to, presumably, the anonymous inner class, producing as output:

     20:14:18.908 TRACE [biz.ianw.lanchecker.Trace] - Enters method:
Logger biz.ianw.lanchecker.MailMail.access$0()
     20:14:18.909 TRACE [biz.ianw.lanchecker.Trace] - Exits method:
Logger biz.ianw.lanchecker.MailMail.access$0().
     20:14:18.909 TRACE [biz.ianw.lanchecker.Trace] -   with return
value: Logger[biz.ianw.lanchecker.MailMail]
     20:14:18.909 DEBUG [biz.ianw.lanchecker.MailMail] - DEBUG:
getProvider() returning
javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]

I added the rather overly broad

     && !within( is(AnonymousType) )

condition to the pointcut, as shown above, but it had no effect. In fact
I'm having real difficulty finding is(AnonymousType) documented anywhere.

How can I write a pointcut that excludes this anonymous inner method,
preferably without impacting any others I may wish to log in future?

Ian

(Originally posted this 5 days ago on SO, but haven't had any replies)


_______________________________________________
aspectj-users mailing list
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to exclude an anonymous inner method from a pointcut?

Andy Clement
Sorry I didn’t see it on StackOverflow - I do hang around there too when I can!

The access$0 method has been added to MailMail because log is private in MailMail - it enables the log.debug(line) to access log from the anonymous class (presumably called MailMail$1).

Recognizing that, we can see that access$0 is not in the anonymous class, it is an accessor generated in the MailMail class, hence your additional pointcut fragment not working.

Couple of options:

Exclude it specifically:
       pointcut anyMethodExecuted():       execution (* biz.ianw.lanchecker.*.*(..)) && !within(Trace) && !execution(* MailMail.access$0(..));

Exclude all synthetic accessors (it is considered synthetic because it is ‘generated’ by the compiler to support what you are doing):
       pointcut anyMethodExecuted():       execution (* biz.ianw.lanchecker.*.*(..)) && !within(Trace) && !execution(synthetic * access$*(..));

Or you could exclude all synthetics perhaps:
       pointcut anyMethodExecuted():       execution (!synthetic * biz.ianw.lanchecker.*.*(..)) && !within(Trace);

cheers,
Andy

> On Nov 11, 2015, at 6:50 AM, Ian Worthington <[hidden email]> wrote:
>
> I have an AspectJ trace routine set up to log method entry and exit conditions using the following pointcuts:
>
>    public aspect Trace {
>        pointcut anyMethodExecuted():       execution (* biz.ianw.lanchecker.*.*(..)) && !within(Trace); // && !within( is(AnonymousType) );
>        pointcut anyConstructorExecuted():  execution (biz.ianw.lanchecker.*.new(..)) && !within(Trace);
>
>
> In my email class I have a method which calls the setDebugOut method to redirect the debug output to a LogOutputStream:
>
>    final private static  Logger log = LoggerFactory.getLogger(MailMail.class);
>    ...
>    LogOutputStream losStdOut = new LogOutputStream() {
>        @Override
>        protected void processLine(String line, int level) {
>            log.debug(line);
>        }
>    };
>
>    public void sendPlainHtmlMessage(...) {
>        Session session = javaMailSender.getSession();
>        PrintStream printStreamLOS = new PrintStream(losStdOut);
>        session.setDebugOut(printStreamLOS);
>        ...
>
> This works fine, except that the Trace class pointcut intercepts the call to, presumably, the anonymous inner class, producing as output:
>
>    20:14:18.908 TRACE [biz.ianw.lanchecker.Trace] - Enters method: Logger biz.ianw.lanchecker.MailMail.access$0()
>    20:14:18.909 TRACE [biz.ianw.lanchecker.Trace] - Exits method: Logger biz.ianw.lanchecker.MailMail.access$0().
>    20:14:18.909 TRACE [biz.ianw.lanchecker.Trace] -   with return value: Logger[biz.ianw.lanchecker.MailMail]
>    20:14:18.909 DEBUG [biz.ianw.lanchecker.MailMail] - DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
>
> I added the rather overly broad
>
>    && !within( is(AnonymousType) )
>
> condition to the pointcut, as shown above, but it had no effect. In fact I'm having real difficulty finding is(AnonymousType) documented anywhere.
>
> How can I write a pointcut that excludes this anonymous inner method, preferably without impacting any others I may wish to log in future?
>
> Ian
>
> (Originally posted this 5 days ago on SO, but haven't had any replies)
>
>
> _______________________________________________
> aspectj-users mailing list
> [hidden email]
> To change your delivery options, retrieve your password, or unsubscribe from this list, visit
> https://dev.eclipse.org/mailman/listinfo/aspectj-users

_______________________________________________
aspectj-users mailing list
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to exclude an anonymous inner method from a pointcut?

Ian Worthington
Many thanks Andy for this most comprehensive explanation.  For now I've
excluded synthetic accessors.  What other types of synthetics might I
encounter?  Is there some documentation somewhere you could recommend?

Is it worth keeping the log as private?  There's no leakage of access
control by removing this.

Is there any way I can see what additional methods the compiler
generates?  In the olden days I would have checked the compiler listing
but I haven't seen one of those out of Java.

Post on SO is at
http://stackoverflow.com/questions/33558253/how-to-exclude-an-anonymous-inner-method-from-a-pointcut,
tagged Aspectj, AOP, and Java. Should I have used something else? For
completeness I'd like to add your answer there if I may?

Thanks again,

Ian

On 12-Nov-15 15:25, Andy Clement wrote:

> Sorry I didn’t see it on StackOverflow - I do hang around there too when I can!
>
> The access$0 method has been added to MailMail because log is private in MailMail - it enables the log.debug(line) to access log from the anonymous class (presumably called MailMail$1).
>
> Recognizing that, we can see that access$0 is not in the anonymous class, it is an accessor generated in the MailMail class, hence your additional pointcut fragment not working.
>
> Couple of options:
>
> Exclude it specifically:
>         pointcut anyMethodExecuted():       execution (* biz.ianw.lanchecker.*.*(..)) && !within(Trace) && !execution(* MailMail.access$0(..));
>
> Exclude all synthetic accessors (it is considered synthetic because it is ‘generated’ by the compiler to support what you are doing):
>         pointcut anyMethodExecuted():       execution (* biz.ianw.lanchecker.*.*(..)) && !within(Trace) && !execution(synthetic * access$*(..));
>
> Or you could exclude all synthetics perhaps:
>         pointcut anyMethodExecuted():       execution (!synthetic * biz.ianw.lanchecker.*.*(..)) && !within(Trace);
>
> cheers,
> Andy
>
>> On Nov 11, 2015, at 6:50 AM, Ian Worthington <[hidden email]> wrote:
>>
>> I have an AspectJ trace routine set up to log method entry and exit conditions using the following pointcuts:
>>
>>     public aspect Trace {
>>         pointcut anyMethodExecuted():       execution (* biz.ianw.lanchecker.*.*(..)) && !within(Trace); // && !within( is(AnonymousType) );
>>         pointcut anyConstructorExecuted():  execution (biz.ianw.lanchecker.*.new(..)) && !within(Trace);
>>
>>
>> In my email class I have a method which calls the setDebugOut method to redirect the debug output to a LogOutputStream:
>>
>>     final private static  Logger log = LoggerFactory.getLogger(MailMail.class);
>>     ...
>>     LogOutputStream losStdOut = new LogOutputStream() {
>>         @Override
>>         protected void processLine(String line, int level) {
>>             log.debug(line);
>>         }
>>     };
>>
>>     public void sendPlainHtmlMessage(...) {
>>         Session session = javaMailSender.getSession();
>>         PrintStream printStreamLOS = new PrintStream(losStdOut);
>>         session.setDebugOut(printStreamLOS);
>>         ...
>>
>> This works fine, except that the Trace class pointcut intercepts the call to, presumably, the anonymous inner class, producing as output:
>>
>>     20:14:18.908 TRACE [biz.ianw.lanchecker.Trace] - Enters method: Logger biz.ianw.lanchecker.MailMail.access$0()
>>     20:14:18.909 TRACE [biz.ianw.lanchecker.Trace] - Exits method: Logger biz.ianw.lanchecker.MailMail.access$0().
>>     20:14:18.909 TRACE [biz.ianw.lanchecker.Trace] -   with return value: Logger[biz.ianw.lanchecker.MailMail]
>>     20:14:18.909 DEBUG [biz.ianw.lanchecker.MailMail] - DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
>>
>> I added the rather overly broad
>>
>>     && !within( is(AnonymousType) )
>>
>> condition to the pointcut, as shown above, but it had no effect. In fact I'm having real difficulty finding is(AnonymousType) documented anywhere.
>>
>> How can I write a pointcut that excludes this anonymous inner method, preferably without impacting any others I may wish to log in future?
>>
>> Ian
>>
>> (Originally posted this 5 days ago on SO, but haven't had any replies)
>>
>>
>> _______________________________________________
>> aspectj-users mailing list
>> [hidden email]
>> To change your delivery options, retrieve your password, or unsubscribe from this list, visit
>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
> _______________________________________________
> aspectj-users mailing list
> [hidden email]
> To change your delivery options, retrieve your password, or unsubscribe from this list, visit
> https://dev.eclipse.org/mailman/listinfo/aspectj-users

_______________________________________________
aspectj-users mailing list
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to exclude an anonymous inner method from a pointcut?

Andy Clement
Synthetics are not spec’d as such, and compilers may choose to generate different things (so javac might generate a particular kind of accessor, whilst the eclipse java compiler generates something different - although they both have the same effect). I wrote something on a particular case related to constructors a while back: http://andrewclement.blogspot.ca/2009/03/compiler-variation.html

Where you might see them:
- accessors you’ve hit already
- bridge methods. So when you subclass something involving generics a bridge method may be created to ‘bridge the gap’ between the concrete generics in your subtype and the generic bounds specified in the superclass.
- constructors when using non static inner types (I cover that case in the article above).

There are probably some others I’m forgetting at the moment.

Could make log non private to avoid it, I guess.

I use ‘javap -private’ against my classes to see what methods have ended up in there but I’d say usually you can ignore synthetics being in use and not worry about them.

>  For completeness I'd like to add your answer there if I may?

Feel free, you had the right tags on that Q. I probably had a digest email about it but overlooked it, sorry about that.

cheers,
Andy

> On Nov 13, 2015, at 10:39 AM, Ian Worthington <[hidden email]> wrote:
>
> Many thanks Andy for this most comprehensive explanation.  For now I've excluded synthetic accessors.  What other types of synthetics might I encounter?  Is there some documentation somewhere you could recommend?
>
> Is it worth keeping the log as private?  There's no leakage of access control by removing this.
>
> Is there any way I can see what additional methods the compiler generates?  In the olden days I would have checked the compiler listing but I haven't seen one of those out of Java.
>
> Post on SO is at http://stackoverflow.com/questions/33558253/how-to-exclude-an-anonymous-inner-method-from-a-pointcut, tagged Aspectj, AOP, and Java. Should I have used something else? For completeness I'd like to add your answer there if I may?
>
> Thanks again,
>
> Ian
>
> On 12-Nov-15 15:25, Andy Clement wrote:
>> Sorry I didn’t see it on StackOverflow - I do hang around there too when I can!
>>
>> The access$0 method has been added to MailMail because log is private in MailMail - it enables the log.debug(line) to access log from the anonymous class (presumably called MailMail$1).
>>
>> Recognizing that, we can see that access$0 is not in the anonymous class, it is an accessor generated in the MailMail class, hence your additional pointcut fragment not working.
>>
>> Couple of options:
>>
>> Exclude it specifically:
>>        pointcut anyMethodExecuted():       execution (* biz.ianw.lanchecker.*.*(..)) && !within(Trace) && !execution(* MailMail.access$0(..));
>>
>> Exclude all synthetic accessors (it is considered synthetic because it is ‘generated’ by the compiler to support what you are doing):
>>        pointcut anyMethodExecuted():       execution (* biz.ianw.lanchecker.*.*(..)) && !within(Trace) && !execution(synthetic * access$*(..));
>>
>> Or you could exclude all synthetics perhaps:
>>        pointcut anyMethodExecuted():       execution (!synthetic * biz.ianw.lanchecker.*.*(..)) && !within(Trace);
>>
>> cheers,
>> Andy
>>
>>> On Nov 11, 2015, at 6:50 AM, Ian Worthington <[hidden email]> wrote:
>>>
>>> I have an AspectJ trace routine set up to log method entry and exit conditions using the following pointcuts:
>>>
>>>    public aspect Trace {
>>>        pointcut anyMethodExecuted():       execution (* biz.ianw.lanchecker.*.*(..)) && !within(Trace); // && !within( is(AnonymousType) );
>>>        pointcut anyConstructorExecuted():  execution (biz.ianw.lanchecker.*.new(..)) && !within(Trace);
>>>
>>>
>>> In my email class I have a method which calls the setDebugOut method to redirect the debug output to a LogOutputStream:
>>>
>>>    final private static  Logger log = LoggerFactory.getLogger(MailMail.class);
>>>    ...
>>>    LogOutputStream losStdOut = new LogOutputStream() {
>>>        @Override
>>>        protected void processLine(String line, int level) {
>>>            log.debug(line);
>>>        }
>>>    };
>>>
>>>    public void sendPlainHtmlMessage(...) {
>>>        Session session = javaMailSender.getSession();
>>>        PrintStream printStreamLOS = new PrintStream(losStdOut);
>>>        session.setDebugOut(printStreamLOS);
>>>        ...
>>>
>>> This works fine, except that the Trace class pointcut intercepts the call to, presumably, the anonymous inner class, producing as output:
>>>
>>>    20:14:18.908 TRACE [biz.ianw.lanchecker.Trace] - Enters method: Logger biz.ianw.lanchecker.MailMail.access$0()
>>>    20:14:18.909 TRACE [biz.ianw.lanchecker.Trace] - Exits method: Logger biz.ianw.lanchecker.MailMail.access$0().
>>>    20:14:18.909 TRACE [biz.ianw.lanchecker.Trace] -   with return value: Logger[biz.ianw.lanchecker.MailMail]
>>>    20:14:18.909 DEBUG [biz.ianw.lanchecker.MailMail] - DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
>>>
>>> I added the rather overly broad
>>>
>>>    && !within( is(AnonymousType) )
>>>
>>> condition to the pointcut, as shown above, but it had no effect. In fact I'm having real difficulty finding is(AnonymousType) documented anywhere.
>>>
>>> How can I write a pointcut that excludes this anonymous inner method, preferably without impacting any others I may wish to log in future?
>>>
>>> Ian
>>>
>>> (Originally posted this 5 days ago on SO, but haven't had any replies)
>>>
>>>
>>> _______________________________________________
>>> aspectj-users mailing list
>>> [hidden email]
>>> To change your delivery options, retrieve your password, or unsubscribe from this list, visit
>>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>> _______________________________________________
>> aspectj-users mailing list
>> [hidden email]
>> To change your delivery options, retrieve your password, or unsubscribe from this list, visit
>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>
> _______________________________________________
> aspectj-users mailing list
> [hidden email]
> To change your delivery options, retrieve your password, or unsubscribe from this list, visit
> https://dev.eclipse.org/mailman/listinfo/aspectj-users

_______________________________________________
aspectj-users mailing list
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users
Loading...