Wir haben in unserem Projekt den Effekt, dass im TaskExecutor ausgeführte Runnables die auf Session-Scoped Beans zugreifen "merkwürdige" Effekte im Jetty Umfeld geschehen. Alles in einem Satz erklärt ;)
Die Effekte sind kritisch da unterschiedliche User-Sessions vermischt werden.
Wir vermuten dass es durch die wiederverwendeten Request-Objekte von jetty dazu kommt.
Spring holt sich die Session Informationen aus den ThreadLocal Session-Request-Attributen.
In unserem Workaround kopieren wir den Request nochmal in den ThreadLocal bevor das Runnable
Maybe there is a bug with the TaskExecutor because spring gets session information from ThreadLocal request attributes ... I guess.
Because of Jetty uses Request Objects more than one time ("recycling"), multiple user session will be mixed up ... so this is critical for us.
In our workaround we copy the request into the ThreadLocal again before we start the Runnable.
There is unfortunately (still) no portable solution for this, since request objects may indeed be reused...
Technically, a Servlet API request object is only guaranteed to be valid during the processing of the initial request (i.e. during the Servlet.service call in the original Servlet container thread that called the service method). And in case of a asynchronous Runnables, we are basically taking the request reference and passing it on to some other thread, which may or may not execute while the request object is still active in the original processing thread.
Servlet 3.0 changes the semantics here a bit, although it isn't clear what that will mean for scoped beans yet: It certainly won't work out of the box but will rather require some special suspending and resuming of request processing, and special servlet configuration - which probably is overkill for simple async access to request and session attributes. In any case, up until Servlet 2.5, I'm afraid we are facing a fundamental platform limitation here.
Our recommendation is to avoid the retrieval of request/session-scoped beans from asynchronous Runnables, in favor of obtaining those beans first and then passing them to the Runnable as constructor arguments. In other words, you could obtain the scoped bean instances in the original servlet thread, pass them to the Runnable instance, and then call TaskExecutor's execute(Runnable) method. Note that this requires raw scoped beans, i.e. no aop:scoped-proxy.
one year later I have a similar problem ;)
I have a class Worker which gets a "service" via @Autowire, these injected service is a session scoped bean. The worker have a method "doIt" with the @Async annotation. Now when I call doIt() the internal session scoped proxy for "service" can't find the necessary request attributes to resolve the right "real session" bean.
Is there a way/best practice to use session scoped beans in asynchronous tasks?
Maybe the spring task executor can "copy" the needed request attribute(s) for the internal session-scoped-proxies?
I won't do that by myself ;) Because it's a common piece of work, which should be done by spring.