If there are multiple AJAX request in the same time (and same HTTP Session) they can somehow overwrite the concurrent thread's data (for example the result location).
There is no conflict when we use resource URL, but when we use the action URL the struts2 portlet plugin executes the interceptor stack twice:
- First in Action phase: This runs normally the action, and saves the full stack and response location to the http session. The PortletStateInterceptor saves the stack, the PortletResult saves the location.
- Second in Render phase: This phase restores the value stack and runs a dummy action (DirectRenderFromEventAction) which does noting but returns the previously saved response location from the session.
The problem is that key for the http session objects is a constant (Location: RENDER_DIRECT_LOCATION, Valuestack: STACK_FROM_EVENT_PHASE).
Let's see an example, when there are two concurrent thread A,B:
1. A action phase (saves locationA to session(RENDER_DIRECT_LOCATION), saves stackA to session(STACK_FROM_EVENT_PHASE))
2. B action phase (saves locationB to session(RENDER_DIRECT_LOCATION), saves stackB to session(STACK_FROM_EVENT_PHASE), so it overwrites locationA, stackA!)
3. A render phase (loads stackB, locationB from session. Returns/forwards to locationB) So it returns the response of the B thread too!
4. B render phase (loads stackB, locationB from session. Returns/forwards to locationB)
Possible solution is to add the threadId to the session key (RENDER_DIRECT_LOCATION + ThreadId). This could cause a massive load to the session so some clever clean up needed.