http://nagoya.apache.org/bugzilla/show_bug.cgi?id=276

*** shadow/276  Fri Mar  9 19:13:52 2001
--- shadow/276.tmp.11958        Fri Mar  9 19:13:52 2001
***************
*** 0 ****
--- 1,256 ----
+ +============================================================================+
+ | JNI problem: bufferedreader.read fails in Tomcat/IIS/JNI set-up BugRat Rep |
+ +----------------------------------------------------------------------------+
+ |        Bug #: 276                         Product: Tomcat 3                |
+ |       Status: UNCONFIRMED                 Version: 3.2.1 Final             |
+ |   Resolution:                            Platform: All                     |
+ |     Severity: Normal                   OS/Version: All                     |
+ |     Priority: High                      Component: Connectors              |
+ +----------------------------------------------------------------------------+
+ |  Assigned To: [EMAIL PROTECTED]                                             |
+ |  Reported By: [EMAIL PROTECTED]                                       |
+ |      CC list: Cc:                                                          |
+ +----------------------------------------------------------------------------+
+ |          URL:                                                              |
+ +============================================================================+
+ |                              DESCRIPTION                                   |
+ There seems to be a bug that interferes with servlet-to-servlet communication, when 
+Tomcat is running under IIS (Win 2000 Advanced), using JNI.  
+ 
+ I'm attaching source for a pair of simple servlets that demonstrate the bug.  The 
+first servlet (BadClient.java) opens a URLConnection to the second servlet 
+(BadServer.java).   BadClient uses the URLConnection to open an output stream, then 
+uses the output stream to print some text, which will be read by BadServer.  
+ 
+ The BadServer servlet then calls request.getReader to get a reader object, to read 
+the text that was sent by BadClient. 
+ 
+ This all works fine under Tomcat 3.2, when Tomcat is running stand-alone. But if 
+Tomcat 3.2 is running inside IIS, using the JNI connector, there's a problem.   
+BadServer is never able to read any of the text sent by BadClient.   The whole 
+process just seems to hang for exactly 1 minute... apparently, something times out 
+after 1 minute, and BadClient stops trying to read the text.  Under JNI, the read 
+call returns -1.  
+ 
+ (Other servlets work fine under JNI.) 
+ 
+ The two servlets go on and perform other tasks after that, with BadServer reading a 
+local .GIF file, then sending it back to BadClient, which send the image back to the 
+browser.  That part works; it's the first part that fails, as described above. 
+ 
+ I've tried various configurations of Tomcat -- using the JVM.DLL for classic, or 
+hotspot, or server (Java 1.3).   No difference.  I've looked in the various log files 
+for exceptions, and I don't see any.
+ 
+ Here's the source for both servlets (around 100 lines each). If the formatting is 
+messed up too badly, please let me know and I'll email a copy to anyone who wants to 
+investigate the problem. 
+ 
+ // Here is all of BadClient.java (118 lines): 
+ // BadClient.java -- demonstrates behavior that works fine in Tomcat 3.2
+ // but does not work when Tomcat runs under IIS using JNI
+ // Used in conjunction with BadServer.java
+ import javax.servlet.*;
+ import javax.servlet.http.*;
+ import java.io.*;
+ import java.util.*;
+ import java.net.URLConnection;
+ import java.net.URL;
+ 
+ public class BadClient extends HttpServlet {
+ 
+       // TODO:  Either modify the following string literal to represent
+       // the URL of the BadServer servlet, or specify that URL
+       // using an init parameter.
+       String m_url = "http://localhost:8100/test/servlet/BadServer";
+ 
+       public void init(ServletConfig config) throws ServletException {
+               super.init(config);
+               try {
+                       String str = getInitParameter("url");           //URL to 2nd 
+servlet
+                       if (str != null) {
+                               m_url = str;
+                       }
+               }
+               catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+ 
+       public void service(HttpServletRequest request, HttpServletResponse res)
+               throws ServletException, IOException
+       {
+               // Open an URLConnection to the BadServer servlet.
+               URL url = new URL(m_url);
+               URLConnection urlConnection = url.openConnection();
+               urlConnection.setDoOutput(true);
+               urlConnection.setUseCaches(false);
+               urlConnection.setRequestProperty("Connection", "close");
+               OutputStream os = null;
+               try {
+                       os = urlConnection.getOutputStream();
+ 
+                       // Only use one of the following two statements:
+                       //PrintWriter pw = new PrintWriter(os);
+                       OutputStreamWriter pw = new OutputStreamWriter(os);
+ 
+                       System.out.println("BadClient: About to print text. Time:" + 
+new Date());
+ 
+                       // Send some text to the second servlet.  This is the part that
+                       // seems to fail when running on Tomcat 3.2 under IIS using 
+JNI.
+ 
+                       // If using a PrintWriter, use the println method...
+                       /*
+                       if (pw.checkError()) {
+                               System.out.println("BadClient: will do println; 
+checkError is true.");
+                       }
+                       pw.println("This is some text sent from BadClient to 
+BadServer.");
+                       if (pw.checkError()) {
+                               System.out.println("BadClient: just did println; 
+checkError is true.");
+                       }
+                       */
+ 
+                       // ...OR, If using an OutputStreamWriter, use this statement:
+                       pw.write("This is some text sent from BadClient to 
+BadServer...", 0, 50);
+ 
+                       System.out.println("BadClient: Sent text.  Time:" + new 
+Date());
+ 
+                       String foo = request.getParameter("skipflush");
+                       if (foo != null && foo.length() > 0) {
+                               System.out.println("BadClient: Will SKIP the 
+pw.flush...");
+                       }
+                       else {
+                               pw.flush();
+                       }
+ 
+                       foo = request.getParameter("skipclose");
+                       if (foo != null && foo.length() > 0 ) {
+                               System.out.println("Will SKIP the pw.close... ");
+                       }
+                       else {
+                               pw.close();
+                       }
+ 
+                       System.out.println("BadClient:After flush & close. Time:" + 
+new Date());
+               } catch (Exception e) {
+                       System.out.println(e.toString() );
+                       e.printStackTrace();
+               }
+               os.close();
+ 
+               // Fetch an image from the second servlet
+               BufferedInputStream bin =
+                               new BufferedInputStream( 
+urlConnection.getInputStream() );
+ 
+               DataInputStream dis = new DataInputStream(bin);
+ 
+               // Read the text that precedes the image that we'll get back
+               String s = dis.readUTF();
+               System.out.println("BadClient: Read header from BadServer: {" + s + 
+"}");
+ 
+               byte[] buf = new byte[1024];
+               int    count;
+               // now pump the image data to the browser
+               OutputStream outStream = res.getOutputStream();
+               while ((count = dis.read(buf)) != -1) {
+                       outStream.write(buf, 0, count);
+               }
+               outStream.flush();
+               dis.close();
+               outStream.close();
+       }
+ 
+       public String getServletInfo() {
+               return "ClientServlet Info";
+       }
+ }
+ // end of BadClient.java 
+ 
+ //Here is all of BadServer.java (101 lines): 
+ 
+ // BadServer.java -- demonstrates behavior that works fine in Tomcat 3.2
+ // but does not work if Tomcat is running under IIS with JNI.
+ // Used in conjunction with BadClient.java
+ 
+ import javax.servlet.*;
+ import javax.servlet.http.*;
+ import java.io.*;
+ import java.util.*;
+ public class BadServer extends HttpServlet {
+ 
+       public void init(ServletConfig config) throws ServletException {
+               super.init(config);
+       }
+ 
+       public void doPost(HttpServletRequest request, HttpServletResponse res)
+               throws ServletException, IOException {
+ 
+               try {
+                       System.out.println("BadServer: will read text fromclient.:" + 
+new Date());
+ 
+                       // Read in the text sent by the client servlet.
+ 
+                       // Only make one of the following two calls:
+                       useBufferedReader(request);
+                       //useInputStreamReader(request);
+ 
+                       System.out.println("BadServer: read text from the client.:" + 
+new Date());
+               }
+               catch (Exception e) {
+                       System.out.println(e.toString() );
+                       e.printStackTrace();
+               }
+ 
+               // Send the client back some text, followed by a GIF image
+               returnFile(res);
+       }
+ 
+       void useInputStreamReader(HttpServletRequest request)
+                               throws IOException {
+ 
+               String buf = null;
+               int i = 0;
+               try {
+                       InputStream is = request.getInputStream();
+                       InputStreamReader br = new InputStreamReader(is);
+ 
+                       char[] cbuf = new char[1024];
+                       i = br.read(cbuf, 0, 50);
+                       buf = new String(cbuf);
+               } catch (Exception e) {
+                       System.out.println(e.toString() );
+                       e.printStackTrace();
+               }
+               System.out.println("BadServer:read returned " + i + " chars:" + buf);
+       }
+ 
+       void useBufferedReader(HttpServletRequest request)
+                               throws IOException {
+               //InputStream is = request.getInputStream();
+               //BufferedReader br = new BufferedReader(new InputStreamReader(is));
+ 
+               String buf = null;
+               int i = 0;
+               try {
+                       BufferedReader br = request.getReader();
+                       char[] cbuf = new char[1024];
+                       i = br.read(cbuf, 0, 50);  
+                       buf = new String(cbuf);
+               } catch (Exception e) {
+                       System.out.println(e.toString() );
+                       e.printStackTrace();
+               }
+               System.out.println("BadServer:readLine returned " + i + " chars:" + 
+buf);
+       }
+ 
+       void returnFile(HttpServletResponse res)
+                       throws ServletException, IOException {
+ 
+               // TODO:  If necessary, modify the following to point to a local GIF 
+file.
+               File f = new File("D:\\test.gif");
+ 
+               BufferedInputStream bin = new BufferedInputStream(new 
+FileInputStream(f));
+               BufferedOutputStream os = new 
+BufferedOutputStream(res.getOutputStream());
+               DataOutputStream dos = new DataOutputStream(os);
+               dos.writeUTF("Some text sent from BadServer!");
+ 
+               byte[] buf = new byte[1024];
+               int nRead;
+ 
+               while( (nRead = bin.read(buf)) != -1 ) {
+                               os.write(buf, 0, nRead);
+               }
+               os.flush();
+               bin.close();
+               System.out.println("BadServer: Flushed OS.");
+       }
+ 
+       public String getServletInfo() {
+               return "SecondServlet Information";
+       }
+ }
+ // end of BadServer.java 

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to