Java.lang.IllegalStateException: No thread-bound request found, exception in aspect

aspectjjavaspringspring-mvc

Following is my aspect:

    @Configurable
    @Aspect
    public class TimingAspect {

        @Autowired
        private HttpServletRequest httpServletRequest;

        // Generic performance logger for any mothod
        private Object logPerfomanceInfo(ProceedingJoinPoint joinPoint, String remoteAddress) {
            StringBuilder tag = new StringBuilder();
            if (joinPoint.getTarget() != null) {
                tag.append(joinPoint.getTarget().getClass().getName());
                tag.append(".");
            }
            tag.append(joinPoint.getSignature().getName());
            StopWatch stopWatch = new StopWatch(tag.toString());
            Object result = joinPoint.proceed(); // continue on the intercepted method
            stopWatch.stop();

            PerformanceUtils.logInPerf4jFormat(stopWatch.getStartTime(), stopWatch.getElapsedTime(), stopWatch.getTag(), stopWatch.getMessage(), remoteAddress);
            return result;
        }

        @Around("execution(* $$$.$$$.$$$.api.controller.*.*(..))")
        public Object logAroundApis(ProceedingJoinPoint joinPoint) throws Throwable {
            String remoteAddress = null;
            if (httpServletRequest != null) {
               remoteAddress = httpServletRequest.getRemoteAddr();
            }
            return logPerfomanceInfo(joinPoint, remoteAddress);
        }

        @Around("execution(* $$$.$$$.$$$.$$$.$$$.$$$.*(..))")
        public Object logAroundService(ProceedingJoinPoint joinPoint) throws Throwable {
            String remoteAddress = null;
            if (httpServletRequest != null) {
                remoteAddress = httpServletRequest.getRemoteAddr();
            }
            return logPerfomanceInfo(joinPoint, remoteAddress);
        }

I do not get any compile time errors but I do following exception when I start my jetty server:

nested exception is java.lang.IllegalStateException: No thread-bound
request found: Are you referring to request attributes outside of an
actual web request, or processing a request outside of the originally
receiving thread? If you are actually operating within a web request
and still receive this message, your code is probably running outside
of DispatcherServlet/DispatcherPortlet: In this case, use
RequestContextListener or RequestContextFilter to expose the current
request.

One thing to note here is, if I remove "logAroundService" method, I do not get any exceptions.

Best Answer

You shouldn't autowire a HttpServletRequest in your aspect as this will tie your aspect to be only runnable for classes that are called from within an executing HttpServletRequest.

Instead use the RequestContextHolder to get the request when you need one.

private String getRemoteAddress() {
    RequestAttributes attribs = RequestContextHolder.getRequestAttributes();
    if (attribs instanceof NativeWebRequest) {
        HttpServletRequest request = (HttpServletRequest) ((NativeWebRequest) attribs).getNativeRequest();
        return request.getRemoteAddr();
    }
    return null;
}
Related Topic