You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cactus-user@jakarta.apache.org by Daniel Rabe <dr...@opentext.com> on 2004/01/05 22:06:32 UTC

Failure in cactus test with multiple struts forwards

I'm using Cactus with Struts 1.1 (although in this instance, not with
StrutsTestCase). I have a beginXXX method that sets up a request, and a
testXXX method that invokes the service method on my ActionServlet. In most
of my tests, this works great. I have one request, however, that does not
work. I get an error: 

javax.servlet.ServletException: The request object passed to forward() must
be the request object you got from your Cactus test case (i.e. a Cactus
request wrapper object). Instead we got
[org.apache.catalina.core.ApplicationHttpRequest]

The relevant snippet from my struts-config.xml:
<action
	path="/pageOne"
	type="com.opentext.myactions.KPageAction"
	name="pages">
	<forward
		name="pageTwoFwd"
		path="/pageTwo"
		redirect="false"/>
</action>

<action
	path="/pageTwo"
	name="pages"
	forward="/WEB-INF/jsp/pageTwo.jsp">
</action>

My test sets up a request for /pageOne. KPageAction executes, and debug
statements confirm that the request is an instance of
org.apache.cactus.server.HttpServletRequestWrapper. KPageAction returns
actionMapping.findForward( "pageTwoFwd" ). This appears to work okay (based
on TRACE output from struts). The next things I see in my debug output are:
<RequestProcessor> Processing a 'GET' for path '/pageTwo'
<MyRequestProcessor> processPreprocess request: class
org.apache.catalina.core.ApplicationHttpRequest

(MyRequestProcessor is my overridden RequestProcessor class, where I
override processPreprocess. At this point, it looks like the request is back
to being the original request, not the wrapped request.)

I then see:
<RequestProcessor>  Delegating via forward to '/WEB-INF/jsp/pageTwo.jsp'
<MyRequestProcessor> request: class
org.apache.catalina.core.ApplicationHttpRequest
<MyRequestProcessor> response: class
org.apache.coyote.tomcat5.CoyoteResponseFacade
<ServletContextWrapper> <getRequestDispatcher([/WEB-INF/jsp/pageTwo.jsp])
<ApplicationDispatcher> servletPath=/WEB-INF/jsp/pageTwo.jsp, pathInfo=null,
queryString=null, name=null
<ServletContextWrapper> >getRequestDispatcher =
[org.apache.cactus.server.RequestDispatcherWrapper@155035a]
<MyRequestProcessor> rd: class
org.apache.cactus.server.RequestDispatcherWrapper
<ServletContextWrapper> <getRequestDispatcher([/WEB-INF/jsp/pageTwo.jsp])
<ApplicationDispatcher> servletPath=/WEB-INF/jsp/pageTwo.jsp, pathInfo=null,
queryString=null, name=null
<ServletContextWrapper> >getRequestDispatcher =
[org.apache.cactus.server.RequestDispatcherWrapper@4f3ba2]
<RequestDispatcherWrapper>
<forward([org.apache.catalina.core.ApplicationHttpRequest@1d41318],
[org.apache.coyote.tomcat5.CoyoteResponseFacade@94aa42])
ApplicationDispatcher[/cactus-hermes]: Servlet.service() for servlet hermes
threw exception
javax.servlet.ServletException: The request object passed to forward() must
be the request object you got from your Cactus test case (i.e. a Cactus
request wrapper object). Instead we got
[org.apache.catalina.core.ApplicationHttpRequest]

So it looks like the first forward from /pageOne to /pageTwo works, but then
the forward to the actual JSP fails. In this simple example, I can work
around the problem by removing a level of indirection in the
struts-config.xml, defining my pageTwoFwd to forward directly to the JSP
instead of going through the /pageTwo action mapping. However, it seems like
it should work either way. Is this a cactus bug? Struts bug? Or am I doing
something wrong?

Thanks,
Daniel Rabe


RE: Failure in cactus test with multiple struts forwards

Posted by Vincent Massol <vm...@pivolis.com>.
Hi Daniel,

This is strange... :-)

What happens is that Cactus creates wrapper objects for your test case
(i.e. the request, response, context object that you get when extending
ServletTestCase). One of them is RequestDispatcherWrapper which has a
forward() method accepting a HttpServletRequest object assumed to be a
Cactus HttpServletRequestWrapper object.

It seems in your case that it was passed (somehow) a not-wrapped
HttpServletRequest object, thus leading to the exception. Here's the
Cactus code:

public void forward(ServletRequest theRequest, ServletResponse
theResponse)
    throws IOException, ServletException
{
    // If the request is not our request wrapper, then someone is doing
    // something wrong!
    if (!HttpServletRequestWrapper.class.isAssignableFrom(
        theRequest.getClass()))
    {
         throw new ServletException("The request object passed to "
            + "forward() must be the request object you got from your "
            + "Cactus test case (i.e. a Cactus request wrapper object).
"
            + "Instead we got [" + theRequest.getClass().getName() +
"]");
    }       

    HttpServletRequestWrapper request = 
        (HttpServletRequestWrapper) theRequest;

    this.originalDispatcher.forward(request.getOriginalRequest(), 
        theResponse);
}

What I don't understand yet is how could our RequestDispatcherWrapper be
passed a non-wrapped HttpServletRequest object. Maybe it means that our
RequestDispatcherWrapper is saved internally by Struts and then reused
by Struts itself, passing to it a standard http request...

Hmmm....

In any case, I have just fixed it in CVS. If you could try it that would
be great. I'll be doing a nightly build sometime tonight.

Thanks
-Vincent

> -----Original Message-----
> From: Daniel Rabe [mailto:drabe@opentext.com]
> Sent: 05 January 2004 22:07
> To: Cactus Users List
> Subject: Failure in cactus test with multiple struts forwards
> 
> I'm using Cactus with Struts 1.1 (although in this instance, not with
> StrutsTestCase). I have a beginXXX method that sets up a request, and
a
> testXXX method that invokes the service method on my ActionServlet. In
> most
> of my tests, this works great. I have one request, however, that does
not
> work. I get an error:
> 
> javax.servlet.ServletException: The request object passed to forward()
> must
> be the request object you got from your Cactus test case (i.e. a
Cactus
> request wrapper object). Instead we got
> [org.apache.catalina.core.ApplicationHttpRequest]
> 
> The relevant snippet from my struts-config.xml:
> <action
> 	path="/pageOne"
> 	type="com.opentext.myactions.KPageAction"
> 	name="pages">
> 	<forward
> 		name="pageTwoFwd"
> 		path="/pageTwo"
> 		redirect="false"/>
> </action>
> 
> <action
> 	path="/pageTwo"
> 	name="pages"
> 	forward="/WEB-INF/jsp/pageTwo.jsp">
> </action>
> 
> My test sets up a request for /pageOne. KPageAction executes, and
debug
> statements confirm that the request is an instance of
> org.apache.cactus.server.HttpServletRequestWrapper. KPageAction
returns
> actionMapping.findForward( "pageTwoFwd" ). This appears to work okay
> (based
> on TRACE output from struts). The next things I see in my debug output
> are:
> <RequestProcessor> Processing a 'GET' for path '/pageTwo'
> <MyRequestProcessor> processPreprocess request: class
> org.apache.catalina.core.ApplicationHttpRequest
> 
> (MyRequestProcessor is my overridden RequestProcessor class, where I
> override processPreprocess. At this point, it looks like the request
is
> back
> to being the original request, not the wrapped request.)
> 
> I then see:
> <RequestProcessor>  Delegating via forward to
'/WEB-INF/jsp/pageTwo.jsp'
> <MyRequestProcessor> request: class
> org.apache.catalina.core.ApplicationHttpRequest
> <MyRequestProcessor> response: class
> org.apache.coyote.tomcat5.CoyoteResponseFacade
> <ServletContextWrapper>
<getRequestDispatcher([/WEB-INF/jsp/pageTwo.jsp])
> <ApplicationDispatcher> servletPath=/WEB-INF/jsp/pageTwo.jsp,
> pathInfo=null,
> queryString=null, name=null
> <ServletContextWrapper> >getRequestDispatcher =
> [org.apache.cactus.server.RequestDispatcherWrapper@155035a]
> <MyRequestProcessor> rd: class
> org.apache.cactus.server.RequestDispatcherWrapper
> <ServletContextWrapper>
<getRequestDispatcher([/WEB-INF/jsp/pageTwo.jsp])
> <ApplicationDispatcher> servletPath=/WEB-INF/jsp/pageTwo.jsp,
> pathInfo=null,
> queryString=null, name=null
> <ServletContextWrapper> >getRequestDispatcher =
> [org.apache.cactus.server.RequestDispatcherWrapper@4f3ba2]
> <RequestDispatcherWrapper>
> <forward([org.apache.catalina.core.ApplicationHttpRequest@1d41318],
> [org.apache.coyote.tomcat5.CoyoteResponseFacade@94aa42])
> ApplicationDispatcher[/cactus-hermes]: Servlet.service() for servlet
> hermes
> threw exception
> javax.servlet.ServletException: The request object passed to forward()
> must
> be the request object you got from your Cactus test case (i.e. a
Cactus
> request wrapper object). Instead we got
> [org.apache.catalina.core.ApplicationHttpRequest]
> 
> So it looks like the first forward from /pageOne to /pageTwo works,
but
> then
> the forward to the actual JSP fails. In this simple example, I can
work
> around the problem by removing a level of indirection in the
> struts-config.xml, defining my pageTwoFwd to forward directly to the
JSP
> instead of going through the /pageTwo action mapping. However, it
seems
> like
> it should work either way. Is this a cactus bug? Struts bug? Or am I
doing
> something wrong?
> 
> Thanks,
> Daniel Rabe