I have the Problem, that I want to outsource some processes of my Spring WebMVC application into separate Threads. That was easy enough and works, until I want to use a class, userRightService, which uses the global request. That's not available in the threads, and we get a problem, that's pretty much understandable.
This is my Error:
java.lang.RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.userRightsService': Scope 'request' 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: Cannot ask for request attribute - request is not active anymore!
Okay, clear enough. I am trying to keep the request context by implementing this solution:
How to enable request scope in async task executor
This is my runnable class:
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS) public class myThread implements Runnable { private RequestAttributes context; public DataExportThread(RequestAttributes context) { this.context = context; } public void run() { RequestContextHolder.setRequestAttributes(context);
And this where it gets spawned:
final DataExportThread dataExportThread = new myThread(RequestContextHolder.currentRequestAttributes()); final Thread thread = new Thread(myThread); thread.setUncaughtExceptionHandler((t, e) -> {...}); thread.start();
As far as I understood, we store the currentRequestAttributes in the thread and then, when running, we restore them currentRequestAttributes... sounded solid to me, but the error is still there. I think I made some mistake adapting the solution for my case. maybe someone can help me finding the error.
Before I went through a lot of stackoverflow-threads with different solutions (see below), so I could try something else next, but this one seemed the clearest and simplest to me, so I hope someone could help me finding the mistake in the implementation or explain why it's the wrong approach.
- Scope 'session' is not active for the current thread; IllegalStateException: No thread-bound request found
- Accessing request scoped beans in a multi-threaded web application
- Using a request scoped bean outside of an actual web request
- InheritableThreadLocal value not inherited by ExecutorService threads
- How to enable request scope in async task executor
- Setting ThreadContext for all threads in application
- Spring mvc request scope context across threads
I already tried this one without success:
If it's matters:
<org.springframework-version>4.3.4.RELEASE</org.springframework-version>
BTW: I know that it would be better to restructure the application in a way, that the request is not needed in the thread but that's very complicated in that case and I really hope I could avoid this.
--
Edit1:
The Bean which can not be created in the thread starts like this:
@Service("userRightsService") @Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS) public class UserRightsService {
--
Edit2:
I also tried this one:
But context is always empty...
1 Answers
Answers 1
I couldn't reproduce the problem as I am not sure how are you creating/injecting the UserRightsService
but I have a couple of suggestions that you may try.
I guess that the problem is that the RequestAttributes
is invalidated as the request is over (that's why the exception says Cannot ask for request attribute - request is not active anymore
), which happens as your task is running.
Instead, you could try injecting the UserRightsService
where your thread is spawned and pass this instance as an argument to the thread. That way the UserRightsService
should be created without problem as the request should be still available.
Even so, trying to access the RequestAttributes
after the request is over will probably fail. In that case I propose to make a copy of all the values that you need before the request is over, i.e. before your run the thread.
If that doesn't work for you please provide some more info regarding how you initialize the UserRightsService
inside the task.
Good luck!
P.S.: I think that the scope annotation in your thread class is useless as the task object is created manually and not managed by spring.
0 comments:
Post a Comment