[spring] Scope 'session' is not active for the current thread; IllegalStateException: No thread-bound request found

I have a controller that I'd like to be unique per session. According to the spring documentation there are two details to the implementation:

1. Initial web configuration

To support the scoping of beans at the request, session, and global session levels (web-scoped beans), some minor initial configuration is required before you define your beans.

I've added the following to my web.xml as shown in the documentation:

<listener>
  <listener-class>
    org.springframework.web.context.request.RequestContextListener
  </listener-class>
</listener>

2. Scoped beans as dependencies

If you want to inject (for example) an HTTP request scoped bean into another bean, you must inject an AOP proxy in place of the scoped bean.

I've annotated the bean with @Scope providing the proxyMode as shown below:

@Controller
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class ReportBuilder implements Serializable {
    ...
    ...
}

Problem

In spite of the above configuration, I get the following exception:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.reportBuilder': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; 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.

Update 1

Below is my component scan. I have the following in web.xml:

<context-param>
  <param-name>contextClass</param-name>
  <param-value>
    org.springframework.web.context.support.AnnotationConfigWebApplicationContext
  </param-value>
</context-param>

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>org.example.AppConfig</param-value>
</context-param>

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

And the following in AppConfig.java:

@Configuration
@EnableAsync
@EnableCaching
@ComponentScan("org.example")
@ImportResource("classpath:applicationContext.xml")
public class AppConfig implements AsyncConfigurer {
  ...
  ...
}

Update 2

I've created a reproducible test case. This is a much smaller project, so there are differences, but the same error happens. There's quite a few files, so I've uploaded it as a tar.gz to megafileupload.

This question is related to spring wicket

The answer is


Had the same error when I had @Order annotation on a filter class. Even thou I added the filter through the HttpSecurity chain.

Removed the @Order and it worked.


As per documentation:

If you are accessing scoped beans within Spring Web MVC, i.e. within a request that is processed by the Spring DispatcherServlet, or DispatcherPortlet, then no special setup is necessary: DispatcherServlet and DispatcherPortlet already expose all relevant state.

If you are runnning outside of Spring MVC ( Not processed by DispatchServlet) you have to use the RequestContextListener Not just ContextLoaderListener .

Add the following in your web.xml

   <listener>
            <listener-class>
                    org.springframework.web.context.request.RequestContextListener 
            </listener-class>
    </listener>        

That will provide session to Spring in order to maintain the beans in that scope

Update : As per other answers , the @Controller only sensible when you are with in Spring MVC Context, So the @Controller is not serving actual purpose in your code. Still you can inject your beans into any where with session scope / request scope ( you don't need Spring MVC / Controller to just inject beans in particular scope) .

Update : RequestContextListener exposes the request to the current Thread only.
You have autowired ReportBuilder in two places

1. ReportPage - You can see Spring injected the Report builder properly here, because we are still in Same web Thread. i did changed the order of your code to make sure the ReportBuilder injected in ReportPage like this.

log.info("ReportBuilder name: {}", reportBuilder.getName());
reportController.getReportData();

i knew the log should go after as per your logic , just for debug purpose i added .


2. UselessTasklet - We got exception , here because this is different thread created by Spring Batch , where the Request is not exposed by RequestContextListener.


You should have different logic to create and inject ReportBuilder instance to Spring Batch ( May Spring Batch Parameters and using Future<ReportBuilder> you can return for future reference)


You just need to define in your bean where you need a different scope than default singleton scope except prototype. For example:

<bean id="shoppingCart" 
   class="com.xxxxx.xxxx.ShoppingCartBean" scope="session">
   <aop:scoped-proxy/> 
</bean>

https://stackoverflow.com/a/30640097/2569475

For This Issue check My answer at above given url

Using a request scoped bean outside of an actual web request


If anyone else stuck on same point, following solved my problem.

In web.xml

 <listener>
            <listener-class>
                    org.springframework.web.context.request.RequestContextListener 
            </listener-class>
  </listener>

In Session component

@Component
@Scope(value = "session",  proxyMode = ScopedProxyMode.TARGET_CLASS)

In pom.xml

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.1</version>
    </dependency>

My answer refers to a special case of the general problem the OP describes, but I'll add it just in case it helps somebody out.

When using @EnableOAuth2Sso, Spring puts an OAuth2RestTemplate on the application context, and this component happens to assume thread-bound servlet-related stuff.

My code has a scheduled async method that uses an autowired RestTemplate. This isn't running inside DispatcherServlet, but Spring was injecting the OAuth2RestTemplate, which produced the error the OP describes.

The solution was to do name-based injection. In the Java config:

@Bean
public RestTemplate pingRestTemplate() {
    return new RestTemplate();
}

and in the class that uses it:

@Autowired
@Qualifier("pingRestTemplate")
private RestTemplate restTemplate;

Now Spring injects the intended, servlet-free RestTemplate.


I fixed this issue by adding following code in my file.

@Component
@Scope(value = "session",  proxyMode = ScopedProxyMode.TARGET_CLASS)

XML configuration -

<listener>
        <listener-class>
            org.springframework.web.context.request.RequestContextListener 
        </listener-class>
</listener>

Above we can do using Java configuration -

@Configuration
@WebListener
public class MyRequestContextListener extends RequestContextListener {
}

How to add a RequestContextListener with no-xml configuration?

I am using spring version 5.1.4.RELEASE and no need to add below changes in pom.

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.2.10</version>
</dependency>

The problem is not in your Spring annotations but your design pattern. You mix together different scopes and threads:

  • singleton
  • session (or request)
  • thread pool of jobs

The singleton is available anywhere, it is ok. However session/request scope is not available outside a thread that is attached to a request.

Asynchronous job can run even the request or session doesn't exist anymore, so it is not possible to use a request/session dependent bean. Also there is no way to know, if your are running a job in a separate thread, which thread is the originator request (it means aop:proxy is not helpful in this case).


I think your code looks like that you want to make a contract between ReportController, ReportBuilder, UselessTask and ReportPage. Is there a way to use just a simple class (POJO) to store data from UselessTask and read it in ReportController or ReportPage and do not use ReportBuilder anymore?