Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4484411

stack overflow error closing a socket input stream

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 1.4.0
    • 1.4.0
    • core-libs
    • beta2
    • generic
    • generic



      Name: bsC130419 Date: 07/25/2001


      java version "1.4.0-beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b65)
      Java HotSpot(TM) Client VM (build 1.4.0-beta-b65, mixed mode)

      The following test program sends a string to the echo server and retrieves it
      back. It is only a slight extension of the echo demo found in the online
      documentation. This program works properly under the Java 2 jdk 1.3 but causes
      a stack overflow under 1.4 beta.

      Here is the main program:

      package princeton.com.x;

      import java.io.IOException;

      import princeton.com.x.TestSocket;

      public class TestSocketApp
      {
         public static void main(String[] args) throws IOException
         {
            // create a new socket and connect to the echo server
            TestSocket socket = new TestSocket("127.0.0.1", 7);

            // send the command

            socket.WriteToCommandStream
      ( "11111111112222222222333333333344444444445555555555666666666677777777778888888
      88899999999990000000000" );

            // actually send the command buffer to the receiving server

            socket.FlushCommandStream();

            // get the results back

            String replyFromServer = socket.ReadReply().toString();

            // clean up

            socket.close();
         }
      }

      Here is the program where the bug occurs. The stack overflow occurs on line 82
      of this program, e.g. on the line with inputStream.close().

      package princeton.com.x;

      import java.io.*;
      import java.net.*;

      import princeton.com.x.TestSocketReader;
      import princeton.com.x.TestSocketWriter;

      public class TestSocket extends Socket
      {
         StringWriter debugOutputStream;
         TestSocketWriter outputStream;
         TestSocketReader inputStream;

         public TestSocket(String address, int port) throws IOException
         {
            // connect to the parent class socket at the address and port given
            super(address, port);

            // connect buffered streams to a server ...
            // note that the server communicates using 8-bit bytes, but we want to
      use Java strings, which are 16-bit,
            // so we have to account for the conversion using OutputStreamWriter and
      InputStreamReader.

            outputStream = new TestSocketWriter(new OutputStreamWriter(
      super.getOutputStream() ));
            inputStream = new TestSocketReader(new InputStreamReader(
      super.getInputStream() ));

            // for debugging
            debugOutputStream = new StringWriter();
         }

         public StringBuffer ReadReply() throws IOException
         {
            StringBuffer result = inputStream.ReadReply();

            // for debugging
            System.out.println(result);

            return result;
         }

      /*
       * public void WriteCommandBatch(String commandBatch) throws IOException
       * {
       * // for debugging
       * System.out.println(commandBatch);
       *
       * outputStream.WriteCommandBatch(commandBatch);
       * }
       *
       * public void WriteCommandBatch(StringBuffer commandBatch) throws IOException
       * {
       * WriteCommandBatch( commandBatch.toString() );
       * }
       */

         public void WriteToCommandStream(String commandString) throws IOException
         {
            // for debugging
            debugOutputStream.write(commandString);

            outputStream.write(commandString);
         }

         public void WriteToCommandStream(StringBuffer commandString) throws
      IOException
         {
            WriteToCommandStream( commandString.toString() );
         }

         public void FlushCommandStream() throws IOException
         {
            // for debugging
            System.out.println( debugOutputStream.getBuffer() );
            debugOutputStream.close();
            debugOutputStream = new StringWriter();

            outputStream.flush();
         }

         public void close() throws IOException
         {
            debugOutputStream.close();
            inputStream.close();
            outputStream.close();
            super.close();
         }
      }

      Here are the two supporting classes which you need to test this program:

      package princeton.com.x;

      import java.io.*;

      public class TestSocketReader extends BufferedReader
      {
         public TestSocketReader(Reader streamReader) throws IOException
         {
            super(streamReader);
         }

         public StringBuffer ReadReply() throws IOException
         {
            StringBuffer replyString = new StringBuffer();
            char nextChar;
            
            nextChar = (char) read(); // note that read() blocks until a character
      is available
            while ( nextChar != 0 )
            {
               replyString.append(nextChar);
               nextChar = (char) read();
            }

            return replyString;
         }
      }

      (new file starts here)
      package princeton.com.x;

      import java.io.*;

      public class TestSocketWriter extends BufferedWriter
      {
         public TestSocketWriter(Writer streamWriter) throws IOException
         {
            super(streamWriter);
         }

         public void flush() throws IOException
         {
            write(0);
            super.flush();
         }
      /*
       * public void WriteCommandBatch(String commandBatch) throws IOException
       * {
       * write(commandBatch);
       * flush();
       * }
       */
      }

      Here is the output from this program in jdk1.4:

      11111111112222222222333333333344444444445555555555666666666677777777778888888888
      99999999990000000000
      11111111112222222222333333333344444444445555555555666666666677777777778888888888
      99999999990000000000
      java.lang.StackOverflowError
      at java.io.InputStreamReader.close(InputStreamReader.java:535)
      at java.io.BufferedReader.close(BufferedReader.java:502)
      at princeton.com.x.TestSocket.close(TestSocket.java:82)
      at java.net.SocketInputStream.close(SocketInputStream.java:190)
      at java.io.InputStreamReader.close(InputStreamReader.java:538)
      at java.io.BufferedReader.close(BufferedReader.java:502)
      at princeton.com.x.TestSocket.close(TestSocket.java:82)
      at java.net.SocketInputStream.close(SocketInputStream.java:190)
      at java.io.InputStreamReader.close(InputStreamReader.java:538)
      ...
      (1012 lines deleted - repeating sets of the preceding 4 lines)
      ...
      at java.io.BufferedReader.close(BufferedReader.java:502)
      at princeton.com.x.TestSocket.close(TestSocket.java:82)
      at java.net.SocketInputStream.close(SocketInputStream.java:190)
      Exception in thread "main"

      This program appears to operate properly in jdk1.3.
      (Review ID: 128832)
      ======================================================================

            jccollet Jean-Christophe Collet (Inactive)
            bstrathesunw Bill Strathearn (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: