Kim, As Nicholas said, these are interesting issues ! ...
Let me try to answer below. > -----Original Message----- > From: kim [mailto:kim] On Behalf Of Kim Madsen > Sent: 08 February 2002 14:47 > To: [EMAIL PROTECTED] > Subject: Dispatch problem > > I have a few problems with Cactus, which I have been unable to find any > information about. I got several Cactus test cases which works fine, but > the below cases does not work for me. > > I am using JBoss with Tomcat 3.2.3. > > > 1) Problem with dispatching from Servlet to JSP. > > In my Servlet I redirect/dispatch to a JSP template. This works fine, > when running the Servlet without Cactus. But when running my Cactus test > case I get below error every time. This is the code that fails. > > > ServletContext servletContext = getServletContext(); > > javax.servlet.RequestDispatcher requestDispatcher = > servletContext.getNamedDispatcher( template ); > requestDispatcher.forward( req, res ); <------- This goes wrong. > > I have initialized the servlet context first in the Cactus test case: > servlet.init(config); > > This is the error I get: > > java.lang.NullPointerException > at > org.apache.cactus.server.RequestDispatcherWrapper.forward(RequestDispatc he > rWrapper.java:98) > at com.inceptor.rt.Servlet.dispatchError(Servlet.java:164) [snip] I'm currently looking into this. There is indeed a bug in Cactus, in that the Cactus-wrapped getNamedDispatcher() does not return null if the servlet (named "template" in your example) is not found. Instead Cactus returns a request dispatcher wrapper. I have corrected this. It means that now your test will still return a NullPointerException but in _your_ code rather than in Cactus code. The null pointer will happen on the line : requestDispatcher.forward( req, res ); This is normal, it is part of the spec. The spec says to return null if the named servlet cannot be found. Make sure your "template" is in the same context and has an entry in web.xml. Note 1 : I've added a test case in Cactus so that this problem does not happen again. Here it is : public void testGetRequestDispatcherFromNamedDispatcher() throws ServletException, IOException { RequestDispatcher rd = config.getServletContext().getNamedDispatcher("TestJsp"); rd.forward(request, response); } public void endGetRequestDispatcherFromNamedDispatcher(WebResponse theResponse) throws IOException { String result = theResponse.getText(); assertTrue("Page not found, got [" + result + "]", result.indexOf("Hello !") > 0); } "TestJsp" is defined in web.xml as : <servlet> <servlet-name>TestJsp</servlet-name> <jsp-file>/test/test.jsp</jsp-file> </servlet> Note 2 : I've tried it with Tomcat 4.x and Tomcat 3.2.4 and it works fine. However, it fails on Tomcat 3.3.x ... I'll submit a bug report to them as it looks like a bug. > > > 2) Response 404 least to file not found exception: > > For some request my Servlet correct behaviour is to respond with a 404 > Page Not Found. > This works fine when running the servlet without Cactus, however, when > running my Cactus test case I get the below error: > > So the servlet code is: > res.sendError(HttpServletResponse.SC_NOT_FOUND); > res.flushBuffer(); > > The exception I get is: > > java.io.FileNotFoundException: > http://localhost:8080/cactus/ServletRedirector/ [snip] Yes, I know about this issue. Do you know if there is any way to tell HttpURLConnection not to interpret returned codes ? My plan is to move to Commons HttpClient (i.e. replace HttpURLConnection by HttpClient). I already have this issue when testing for a redirect ... I have it commented out in the cactus test case ... It seems this issue is getting more urgent every day ... > > > 3) Synchronization problem. > > In some cases my Servlet sends a redirect flushes the buffer... and then > continues to do some processing for logging. > > response.sendRedirect(redirectURL); > response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); > response.flushBuffer(); > ... more stuff for logging. > > This works fine, as long as the test is run in isolation. However, if I > do 2 of these test after each other I get into trouble because the setUp > method of the second test is run before the tearDown method of the first > test. I have avoided this by inserting a statement in the endXXX method > that makes the first test sleep for 10 seconds - such that the start of > the next test is delayed. > > However, it seems to me that fact that I am flushing the http-response > tricks Cactus into thinking that the test has completed, when in fact > the Servlet is still processing. > This is a complex issue ! In fact, the Client side of Cactus is waiting for the HTTP response. When you do a flush, the server starts sending the response. On the client side, Cactus reads all the data that are on the wire, using : if (this.delegate.getContentLength() != 0) { byte[] buf = new byte[DEFAULT_CHUNK_SIZE]; int count; while (-1 != (count = theInputStream.read(buf))) { theOutputStream.write(buf, 0, count); } } where this.delegate is the InputStream (i.e. response from the Server). The read() method blocks until input data is available, end of file is detected, or an exception is thrown. If you don't close the socket on the server side (by issuing a close()) then I would imagine the read will block and the test will not be finished. If you're doing a close you're actually unsynchronising the response from other work that you still need to perform on the server side. This is fine and even nice in term of response time ! .. argh .... I know remember something I had done in the past and removed ... Ok, here's the story : Previously, I had introduced a semaphore on the test result that is stored in the servlet context ... But I removed some time ago as it was a kludge and couldn't remember why I had put it ... :-( Hum ... Here's what I'll try to do to fix this issue : 1/ At the beginning of each test, reset the context variable holding the result 2/ When the Cactus client asks to get the result, the server side will check if the variable is null or not. If null then it will sleep for a few milliseconds and try again, etc, until it gets a non-null value, signaling that the test is actually finished Thus the second test will not start before the first one is finished. I'll try to add a test case for this first and will keep you informed of the progress. Thanks for these 3 challenging issues ;-) -Vincent > > Any help on any of these 3 issues would greatly be appreciated. > > -- > To unsubscribe, e-mail: <mailto:cactus-user- > [EMAIL PROTECTED]> > For additional commands, e-mail: <mailto:cactus-user- > [EMAIL PROTECTED]> > -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
