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

(fc) FileChannel.read() fails to throw ClosedByInterruptException

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 7
    • 6u21, 6u24, 6u26
    • core-libs
    • b120
    • x86
    • linux, windows_7
    • Verified

      FULL PRODUCT VERSION :
      java version "1.6.0_21"
      Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
      Java HotSpot(TM) 64-Bit Server VM (build 17.0-b16, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.1.7600]

      A DESCRIPTION OF THE PROBLEM :
      When a thread that currently executes FileChannel.read(ByteBuffer) gets interrupted, the read() call returns normally without throwing an exception but still silently closes the channel. The calling thread has no chance to know that the channel was silently closed without explicitely checking each time after calling read().

      This behaviour contradicts the documentation of InterruptibleChannel, that specifies, that an interrupted i/o operation should EITHER throw ClosedByInterruptException and close the channel OR it should return normally without closing the channel. Just silently closing the channel but not throwing the exception is not described as a possible behaviour.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. A large enough (multi-GiBytes) file named "large_test_file" must be in the working directory, to give the reading thread a chance to get interrupted before end of file is reached.
      2. javac Test.java
      3. java Test


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      A java.nio.channels.ClosedByInterruptException gets thrown and the trace printed to the console.

      OR

      The test program terminates without any output (end of file reached).

      ACTUAL -
      The test program prints:

      thread interrupted
      channel closed


      REPRODUCIBILITY :
      This bug can be reproduced often.

      ---------- BEGIN SOURCE ----------
      import java.io.*;
      import java.nio.*;
      import java.nio.channels.*;

      public class Test implements Runnable {

          public static void main(String[] args) throws Exception {
              Thread thread = new Thread(new Test());
              thread.start();
              Thread.sleep(500); // give the new thread some time
              thread.interrupt();
          }

          public void run() {
              try {
                  FileInputStream in = new FileInputStream("large_test_file");
                  FileChannel channel = in.getChannel();
                  ByteBuffer buffer = ByteBuffer.allocate(0x10000);
                  for (;;) {
                      buffer.clear();
                      int r = channel.read(buffer);
                      if (Thread.currentThread().isInterrupted()) {
                          System.out.println("thread interrupted");
                          if (!channel.isOpen()) {
                              System.out.println("channel closed");
                              break;
                          }
                      }
                      if (r < 0)
                          break;
                  }
              } catch (IOException ex) {
                  ex.printStackTrace();
              }
          }
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      A possible although tedious workaround would be to manually check after every i/o operation whether the thread was interrupted, and if so, close the file channel and throw ClosedByInterruptException:

      channel.read(buffer);
      if (Thread.currentThread().isInterrupted()) {
          try {
              channel.close(); // may be redundant
          } finally {
              throw new ClosedByInterruptException();
          }
      }

            alanb Alan Bateman
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: