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

Buffered stream data is discarded by IllegalStateException in 1.4.2 and Tiger

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 6
    • 5.0, 5.0u13, 6
    • core-libs
    • b27
    • generic, x86
    • solaris_10, windows_xp

        There is such big issues as buffered Data lost
        This is because flush operation is not done with IllegalStateException.

        The attached test program works well in 1.3.1_0X(1.4.1_0X also),
        but not in 1.4.2_0X(1.5.beta38).

        REPRODUCE :
         (1) Compile DataLost.java
         (2) Launch "java DataLost windows-31j" in 1.4.2_03(or Tigerbeta38)

             You will see the stack trace as follows.

        K:\nio-lost-data>java DataLost windows-31j
        java.lang.IllegalStateException: Current state = FLUSHED, new state = CODING_END

                at java.nio.charset.CharsetEncoder.throwIllegalStateException(CharsetEnc
        oder.java:939)
                at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:535)
                at sun.nio.cs.StreamEncoder$CharsetSE.flushLeftoverChar(StreamEncoder.ja
        va:358)
                at sun.nio.cs.StreamEncoder$CharsetSE.implClose(StreamEncoder.java:414)
                at sun.nio.cs.StreamEncoder.close(StreamEncoder.java:160)
                at java.io.OutputStreamWriter.close(OutputStreamWriter.java:222)
                at java.io.PrintWriter.close(PrintWriter.java:219)
                at DataLost.testMain(DataLost.java:26)
                at DataLost.main(DataLost.java:5)


        The java.lang.IllegalStateException occurs in 1.4.2( and Tiger b38 ),
        not in 1.3.1(1.4.0).


        INVESTIGATION:

        The following test program outputs some string to a file, "TestFile".
        This program generates an exception intentionally.
         (Please don't consider the sample code has problem.)
        Please consider FileOutputStreamEX class simulates an exception
        in PrintWriter.

          
        ===== Test Program ( DataLost.java ) ====
        import java.io.*;
        class DataLost {

            public static void main( String arg[] ) {
        testMain("TestFile", arg[0]);
            }

            public static void testMain( String filename, String charsetName ) {
        try {
        FileOutputStreamEX fos = new FileOutputStreamEX( filename );
        OutputStreamWriter mosw = new OutputStreamWriter( fos, charsetName);
        PrintWriter pw = new PrintWriter( mosw );

        fos.dontClose();
        for( int i=0;i<100;i++ ){
        pw.write(i+" ");
        }
        try {
        pw.close(); // 1st PrintWriter Close
        }
        catch ( Exception e ) {
        }

        fos.canClose();
        try {
        pw.close(); // 2nd PrintWriter Close
        }
        catch (Exception e ) {
        e.printStackTrace();
        }
        }
        catch (Exception e ) {
        e.printStackTrace();
        }
            }
        }

        class FileOutputStreamEX extends BufferedOutputStream {

            private boolean status;

            FileOutputStreamEX( String str ) throws IOException {
        super( new FileOutputStream( str ) );
            }

            public void dontClose() {
        status = false;
            }

            public void canClose() {
        status = true;
            }

            public void close() throws IOException {
        if ( status == false ) {
        throw new IOException(" can not close ");
        }
        super.close();
            }
        }
        ==========================================

        In the above program, an exception occurs in "1st PrintWriter Close" line.
        Then the program is expected to flush data and close correctly
        in "2nd PrintWriter Close" line.
        However, the flush doesn't run because of exception occurrence.

        This problem happens to
          sun.nio.cs.StreamEncoder$CharsetSE.implClose() .
        If exception, OutputStream.close is not launched.
        As a result, the buffered data in OutputStream is discarded.

        The followings shows when this behavior come to be a problem.


        ==== Sample servlet code =====================
        ....
        public class F extends HttpServlet{
        public void doGet(HttpServletRequest req,HttpServletResponse res)throws ServletException,IOException{

        res.setContentType("text/html;charset=SJIS");
        PrintWriter out = res.getWriter();

        ServletContext sc = getServletContext();
               RequestDispatcher rd = sc.getRequestDispatcher("/jsp/f.jsp");
        rd.forward(req, res); <===(1)

        out.println("</body></html><===(2)
        out.close(); <=== (3)
                }
        }
        .....
        ==============================================

        The above is mini code to explain the problem in licensees app. server.

        According to the specifications of servlet, a program have to do as in (2) and (3)
        once response and request are forwarded.

        In 1.4.2(maybe Tiger also), when an exception occurs in (2) and (3),
        IllegalStateException occurs and flush won't be done as the test program(DataLost.java)
        shows.
        It means that the stream data will not be sent to client.

        In 1.4.0, the program works well.


        PROBLEM:

        - Buffered Data written in stream is discarded.

        =============================================================================

        ###@###.### 2004-03-26

              sherman Xueming Shen
              tbaba Tadayuki Baba (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: