Details
Description
when using the tokenSession interceptor a double submit will end up showing a blank page to the browser.
The server logs show the following stacktrace :
java.lang.NullPointerException at org.apache.catalina.connector.Request.setAttribute(Request.java:1530) at org.apache.catalina.connector.RequestFacade.setAttribute(RequestFacade.java:543) at javax.servlet.ServletRequestWrapper.setAttribute(ServletRequestWrapper.java:239) at org.apache.tiles.servlet.context.ServletRequestScopeMap.put(ServletRequestScopeMap.java:165) at org.apache.tiles.servlet.context.ServletRequestScopeMap.put(ServletRequestScopeMap.java:43) at org.apache.tiles.impl.BasicTilesContainer.getContextStack(BasicTilesContainer.java:470) at org.apache.tiles.impl.BasicTilesContainer.getContext(BasicTilesContainer.java:510) at org.apache.tiles.impl.BasicTilesContainer.getAttributeContext(BasicTilesContainer.java:525) at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:626) at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:322) at org.apache.struts2.views.tiles.TilesResult.doExecute(TilesResult.java:105) at org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186) at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:374)
I founs that this behaviour did not happen in version 2.2.1.1
I checke the Java code and saw a change resposible for the PB :
in version 2.2.1.1 TokenSession.java line 130 to 146 :
protected String doIntercept(ActionInvocation invocation) throws Exception { if (log.isDebugEnabled()) { log.debug("Intercepting invocation to check for valid transaction token."); } //see WW-2902: we need to use the real HttpSession here, as opposed to the map //that wraps the session, because a new wrap is created on every request HttpSession session = ServletActionContext.getRequest().getSession(true); synchronized (session) { if (!TokenHelper.validToken()) { return handleInvalidToken(invocation); } return handleValidToken(invocation); } }
in version 2.3.3 line 140 of TokenSession.java the return handleValidToken(invocation); is no longer protected by the synchronized. That's what causes the problem :
protected String doIntercept(ActionInvocation invocation) throws Exception { if (log.isDebugEnabled()) { log.debug("Intercepting invocation to check for valid transaction token."); } //see WW-2902: we need to use the real HttpSession here, as opposed to the map //that wraps the session, because a new wrap is created on every request HttpSession session = ServletActionContext.getRequest().getSession(true); synchronized (session) { if (!TokenHelper.validToken()) { return handleInvalidToken(invocation); } } return handleValidToken(invocation); }