0

I'm currently trying to add a pointcut around calls to HttpServletResponse.sendRedirect (api doc http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletResponse.html) using aspectj and spring aop. The code for the class and pointcut are as follows:

@Aspect
@Log4j
class ExampleAspect {

    @Before("execution(* javax.servlet.http.HttpServletResponse.sendRedirect(..))")
    void logRedirectBeforeSending() {
          log.warn('holy cow batman, its a redirect!')
    }
}

Currently although the above code compiles it doesn't actually ever execute (as evidenced by a lack of warn output in the log and debug breakpoints in the advice code never being hit).

Although I've omitted them here just for the sake of simplicity the aspect contains other pointcuts which do correctly fire so I have ruled out aspect configuration as a potential cause (which is why I am not including my spring bean configuration).

Further, I have double checked via debugging that a class which implements HttpServletResponse.sendRedirect() is being called when I'm testing my pointcut (if it helps, one of the implementing classes being called is org.apache.catalina.connector.Response https://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/connector/Response.html).

Is there something I'm missing in my pointcut definition that's required when defining a pointcut around an interface? Best I could tell from the Spring AOP documentation it shouldn't require any special syntax.

I've been playing around with variations in the pointcut definition but haven't had any luck yet.

All in all I'm stumped, any ideas?

kmrt
  • 37
  • 6
  • You said that you have other point cuts that fire. Are any of those point cuts associated with an HttpServletResponse? – Jeff Scott Brown Jun 20 '14 at 17:42
  • Ah no I should have mentioned that, other pointcuts that are working are part of the same aspect but are interacting with different classes (namely org.codehaus.groovy.grails.plugins.springsecurity.AjaxAwareAuthenticationSuccessHandler and org.springframework.security.oauth2.provider.token.AbstractTokenGranter) – kmrt Jun 20 '14 at 17:46
  • Are you aware that your aspects are only applied to beans in the application context? – Jeff Scott Brown Jun 20 '14 at 17:53
  • Yes although it is possible I'm misunderstanding what that means so perhaps some context would be helpful here. I'm attempting this pointcut in service of debugging issues with spring security. The redirects I'm expecting are part of the filter chain execution and therefore I'm assuming that these libraries are utilizing spring beans and therefore that I can assume that the beans which I'm attempting to create a join point for are either in my root application context or one of its child contexts and therefore valid candidates. Am I correct in assuming so? – kmrt Jun 20 '14 at 17:58
  • It doesn't matter that the call is being initiated from a Spring bean. It matters that the call is being invoked on a Spring bean. If you for example wrote a point cut to be applied to the `append` method in `StringBuffer` and then you did something like `new StringBuffer().append('something')`, your point cut would not be applied because the `StringBuffer` that you are interacting with is not a Spring bean. I don't know how your app is put together but unless your response is coming out of the Spring context, I don't expect your point cut to be applied. – Jeff Scott Brown Jun 20 '14 at 18:02
  • Ah I suppose you're correct, my assumption that the response object would naturally be injected via spring bean is probably naive. I'd have to dive into the spring security source code to verify but I suppose it is probably more likely due to the nature of responses (namely that a singleton object wouldn't really make sense at all) that it is being instantiated via a new operator instead which would explain why a pointcut isn't going to be an option here. I appreciate the help, if you would like to post that as the answer I'd happily mark it. – kmrt Jun 20 '14 at 18:09

1 Answers1

0

I expect that your response object is not coming from the Spring application context and as such it would not be subject to your aspect.

It doesn't matter that the call is being initiated from a Spring bean. It matters that the call is being invoked on a Spring bean. If you for example wrote a point cut to be applied to the append method in StringBuffer and then you did something like new StringBuffer().append('something'), your point cut would not be applied because the StringBuffer that you are interacting with is not a Spring bean. I don't know how your app is put together but unless your response is coming out of the Spring context, I don't expect your point cut to be applied.

Jeff Scott Brown
  • 26,804
  • 2
  • 30
  • 47
  • Jeff is right, just one additional idea: If you switch from Spring AOP to full-blown AspectJ (which is fully compatible with Spring), you can intercept calls and executions of classes which are *not* Spring beans. AspectJ is much more powerful and also faster than Spring AOP because it does not need dynamic proxies. – kriegaex Jun 21 '14 at 21:36