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

PushbackReader throws NullPointerException

XMLWordPrintable

    • b99
    • x86
    • linux
    • Verified

      FULL PRODUCT VERSION :
      java version "1.8.0_65"
      Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
      Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Linux abc 3.13.0-67-generic #110-Ubuntu SMP Fri Oct 23 13:24:41 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

      A DESCRIPTION OF THE PROBLEM :
      Executing PushbackReader.read() results in a null pointer exception. The documentation for the class clearly says that an IOException will be thrown when read() is invoked after close(). We have handled this for our multithreaded application. But, it appears that, occasionally it can also throw a null pointer exception.

      After looking at the corresponding source code in openjdk, it appears that one of the threads is calling close(). However, the thread that is invoking the read after an unread has already checked for a NPE in ensureOpen() and assumes that the stream is open. When it does a buf.length or buf[pos++], it ends up throwing this NPE.



      REGRESSION. Last worked in version 8u65

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Please see attached code and run it in a loop for 1000 times. It will show a NPE 3-10% of the runs.


      REPRODUCIBILITY :
      This bug can be reproduced often.

      ---------- BEGIN SOURCE ----------
      import java.lang.Exception;
      import java.io.PushbackReader;
      import java.io.*;

      class MyClose extends Thread {
         PushbackReader pr;

         public MyClose(PushbackReader p) {
            pr = p;
         }

         public void run() {
           try {
             pr.close();
           } catch(Exception e) {e.printStackTrace();}
         }
      }

      class MyWriter extends Thread {
         PushbackReader pr;

         public MyWriter(PushbackReader p) {
            pr = p;
         }

         public void run() {
            for(int i = 0; i < 10; i++) {
               try{
                pr.unread(i);
               } catch(Exception e) {e.printStackTrace();}
            }
         }
      }

      class MyReader extends Thread {
         PushbackReader pr;

         public MyReader(PushbackReader p) {
            pr = p;
         }

         public void run() {
            for(int i = 0; i < 100; i++) {
               try {
                pr.read();
               } catch(Exception e) {e.printStackTrace();}
            }
         }

      }

      public class Test extends Thread {
       
         public static void main(String [] args) {

           try {
              String s = "if (a == 4) a = 0;\\n";
              char buf[] = new char[s.length()];
              s.getChars(0, s.length(), buf, 0);
              CharArrayReader in = new CharArrayReader(buf);
              PushbackReader pr = new PushbackReader(in);

              MyReader mr = new MyReader(pr);
              MyWriter mw = new MyWriter(pr);
              MyClose mc = new MyClose(pr);
              mw.start();
              mw.join();
              mr.start();
              mc.start();
       
              mr.join();
              mc.join();
              
           } catch (Exception e) {}
         }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Temp workaround: Let the two reads throw a NPE so that client programs can use this info (may be fix the doc).

      The ideal fix would be to make close() also synchronized like other methods in the class.

            bpb Brian Burkhalter
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: