You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by bu...@apache.org on 2001/03/10 04:13:53 UTC
[Bug 276] New - JNI problem: bufferedreader.read fails in Tomcat/IIS/JNI set-up BugRat Report#518
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: danmil@shore.net |
+ | Reported By: dave_smith@mapinfo.com |
+ | 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: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, email: tomcat-dev-help@jakarta.apache.org