Stripes

Possible race condition with flash scope

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Critical Critical
  • Resolution: Fixed
  • Affects Version/s: Release 1.4.3
  • Fix Version/s: Release 1.5
  • Component/s: ActionBean Dispatching
  • Labels:
    None

Description

From the mailing list:

Hello,
I do redirect and then forward in my code, and it works in most
cases. But sometime (in cca 20% of requests) I get ClassCastException.
The problem occurs not always on the same place, so I'm not able to
write steps to reproduce it - it looks like concurrent access to the
request (wrappers) from more threads. If I make reload of page after
the exception it works fine.
I use Stripes 1.4.3 on Jetty 6.1.8, ActionResolver configured for
.html suffix. Here is my code:

web.xml:
<filter-mapping>
<filter-name>StripesFilter</filter-name>
<servlet-name>StripesDispatcher</servlet-name>
<dispatcher>REQUEST</dispatcher>
<!-- i've tried also this but it didn't help
<dispatcher>FORWARD</dispatcher>
-->
</filter-mapping>

<servlet>
<servlet-name>StripesDispatcher</servlet-name>
<servlet-class>net.sourceforge.stripes.controller.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>StripesDispatcher</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>

============================================
JSP:
<s:form action="/SelectObjects.html" name="objectsForm">
<s:submit name="searchNew">Search</s:submit>
</s:form>

============================================
SelectObjectsActionBean.java:

@DefaultHandler
public Resolution begin() {
return new ForwardResolution("/WEB-INF/jsp/objectList.jsp");
}

public Resolution search() {
return new ForwardResolution("/WEB-INF/jsp/searchForm.jsp");
}

public Resolution searchNew() {
// some logic here
return new RedirectResolution("/SelectObjects.html?search=").flash(this);
}

============================================
Stack trace:
java.lang.ClassCastException: org.mortbay.jetty.Request
at net.sourceforge.stripes.controller.StripesFilter.flashInbound(StripesFilter.java:222)
at net.sourceforge.stripes.controller.StripesFilter.doFilter(StripesFilter.java:179)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:75)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
at org.displaytag.filter.ResponseOverrideFilter.doFilter(ResponseOverrideFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:726)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:206)
at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:324)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:828)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:514)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:450)

Do you have any idea, what could be wrong?
Thanks in advance for your help.

Best regards,

– Josef Cacek

**************

When StripesFilter is cleaning up after a request and an ActionBean is to be flashed, it will swap out the ActionBeanContext's request for a FlashRequest. On the ensuing request, it will look up the bean in flash scope and swap in the new request. But if the cleanup didn't finish before the new request comes in, it can cause a ClassCastException.

Activity

Hide
Ben Gunter added a comment - 15/May/08 11:15 AM

I believe this is fixed in r907. We're using a semaphore to synchronize the cleanup at the end of one request with the stuff at the beginning of the next request. I also added an instanceof check to avoid the ClassCastException. I couldn't actually reproduce this issue on my system so I need anyone who has seen it to try to reproduce it with the new code.

Show
Ben Gunter added a comment - 15/May/08 11:15 AM I believe this is fixed in r907. We're using a semaphore to synchronize the cleanup at the end of one request with the stuff at the beginning of the next request. I also added an instanceof check to avoid the ClassCastException. I couldn't actually reproduce this issue on my system so I need anyone who has seen it to try to reproduce it with the new code.
Hide
Ben Gunter added a comment - 19/May/08 10:44 AM

Never heard back. Works for me so resolving as fixed.

Show
Ben Gunter added a comment - 19/May/08 10:44 AM Never heard back. Works for me so resolving as fixed.

People

Vote (0)
Watch (0)

Dates

  • Created:
    12/May/08 2:04 PM
    Updated:
    04/Jan/11 1:03 PM
    Resolved:
    19/May/08 10:44 AM