Cross context forward java.lang.IllegalStateException: No thread-bound request
found
-------------------------------------------------------------------------------------
Key: COCOON-2254
URL: https://issues.apache.org/jira/browse/COCOON-2254
Project: Cocoon
Issue Type: Bug
Components: - Servlet service framework
Affects Versions: 2.2
Reporter: Andy Bailey
In the case of a cross context forward between 2 web applications, the spring
RequestContextFilter and RequestContextListener are not executed and so
DispatcherServlet I believe should handle this case. The fix I created is
included
(to improve it it should detect if the request was cross context and only
execute in this case.)
Feel free to use the code, part is taken from the spring RequestContextFilter
code so youll have to check the license.
The stack trace of the problem:
java.lang.IllegalStateException: No thread-bound request found: Are you
referring to request attributes outside of an actual web request? If you are
actually operating within a web request and still receive this message,your
code is probably running outside of DispatcherServlet/DispatcherPortlet: In
this case, use RequestContextListener or RequestContextFilter to expose the
current request.
org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:102)
org.apache.cocoon.core.container.spring.avalon.PoolableProxyHandler.invoke(PoolableProxyHandler.java:68)
$Proxy17.setProcessor(Unknown Source)
org.apache.cocoon.components.treeprocessor.TreeProcessor.buildConcreteProcessor(TreeProcessor.java:412)
org.apache.cocoon.components.treeprocessor.TreeProcessor.setupConcreteProcessor(TreeProcessor.java:338)
org.apache.cocoon.components.treeprocessor.TreeProcessor.process(TreeProcessor.java:246)
org.apache.cocoon.servlet.RequestProcessor.process(RequestProcessor.java:351)
org.apache.cocoon.servlet.RequestProcessor.service(RequestProcessor.java:169)
org.apache.cocoon.sitemap.SitemapServlet.service(SitemapServlet.java:84)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.cocoon.servletservice.ServletServiceContext$PathDispatcher.forward(ServletServiceContext.java:468)
org.apache.cocoon.servletservice.ServletServiceContext$PathDispatcher.forward(ServletServiceContext.java:443)
org.apache.cocoon.servletservice.spring.ServletFactoryBean$ServiceInterceptor.invoke(ServletFactoryBean.java:264)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
$Proxy16.service(Unknown Source)
org.apache.cocoon.servletservice.DispatcherServlet.service(DispatcherServlet.java:106)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.tuckey.web.filters.urlrewrite.NormalRewrittenUrl.doRewrite(NormalRewrittenUrl.java:213)
org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:171)
org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:145)
org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:92)
org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:381)
This is my modified version of the Dispatcher Servlet
package com.hazlorealidad.cocoon;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
public class DispatcherServlet extends
org.apache.cocoon.servletservice.DispatcherServlet
{
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
private boolean threadContextInheritable = false;
/**
* Set whether to expose the LocaleContext and RequestAttributes as
* inheritable for child threads (using an
* {...@link java.lang.InheritableThreadLocal}).
* <p>
* Default is "false", to avoid side effects on spawned background
threads.
* Switch this to "true" to enable inheritance for custom child threads
* which are spawned during request processing and only used for this
* request (that is, ending after their initial task, without reuse of
the
* thread).
* <p>
* <b>WARNING:</b> Do not use inheritance for child threads if you are
* accessing a thread pool which is configured to potentially add new
* threads on demand (e.g. a JDK
* {...@link java.util.concurrent.ThreadPoolExecutor}), since this will
expose
* the inherited context to such a pooled thread.
*/
public void setThreadContextInheritable(boolean
threadContextInheritable)
{
this.threadContextInheritable = threadContextInheritable;
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException
{
ServletRequestAttributes attributes = new
ServletRequestAttributes(request);
LocaleContextHolder.setLocale(request.getLocale(),
this.threadContextInheritable);
RequestContextHolder.setRequestAttributes(attributes,
this.threadContextInheritable);
if (logger.isDebugEnabled())
{
logger.debug("Bound request context to thread: " +
request);
}
try
{
super.service(request, response);
}
finally
{
RequestContextHolder.resetRequestAttributes();
LocaleContextHolder.resetLocaleContext();
attributes.requestCompleted();
if (logger.isDebugEnabled())
{
logger.debug("Cleared thread-bound request
context: " + request);
}
}
}
}
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.