Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 923
hrishikeshp19 Avatar asked Jun 03 '14 22:06

hrishikeshp19


4 Answers

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;
}
like image 141
M. Deinum Avatar answered Oct 23 '22 20:10

M. Deinum


@M. Deinum answer doesn't work for me. I use these code instead

RequestAttributes attribs = RequestContextHolder.getRequestAttributes();
if (RequestContextHolder.getRequestAttributes() != null) {
    HttpServletRequest request = ((ServletRequestAttributes) attributes).getRequest();
    return request.getRemoteAddr();
}
like image 29
user1686407 Avatar answered Oct 23 '22 21:10

user1686407


Create bean for RequestContextListener. I got the same error for autowiring HttpServletRequest And the following two lines of code works for me

@Bean
public RequestContextListener requestContextListener() {
    return new RequestContextListener();
}
like image 11
Avijit Biswas Avatar answered Oct 23 '22 22:10

Avijit Biswas


As the error message said: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

To fix it, register a RequestContextListener listener in web.xml file.

<web-app ...>
   <listener>
    <listener-class>
        org.springframework.web.context.request.RequestContextListener
    </listener-class>
   </listener>
</web-app>
like image 7
Nicholas Lu Avatar answered Oct 23 '22 22:10

Nicholas Lu