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

Channels.newWriter() does not close if underlying channel throws an IOException

    XMLWordPrintable

Details

    • b17
    • generic
    • generic
    • Verified

    Description

      ADDITIONAL SYSTEM INFORMATION :
      java -version:
      openjdk version "13-ea" 2019-09-17
      OpenJDK Runtime Environment (build 13-ea+9)
      OpenJDK 64-Bit Server VM (build 13-ea+9, mixed mode, sharing)

      Windows 10 Home, Version 1803, Build 17134.590

      A DESCRIPTION OF THE PROBLEM :
      If the underlying WritableByteChannel errors when closing a sun.nio.cs.StreamEncoder (as returned by Channels.newWriter), then the channel is not closed.

      This is somewhat similar to JDK-6266377, but is not dependent on using a BufferedWriter.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
       - Create a subclass of WritableByteChannel which errors when calling .write, and prints some debugging message when closing.
       - Use Channels.newWriter to wrap an instance of this channel.
       - Write to the writer, and then close it.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The channel would be closed the exception thrown from .write() is propagated.
      ACTUAL -
      The channel is not closed, and the error from .write() is thrown.

      ---------- BEGIN SOURCE ----------
      import java.io.IOException;
      import java.io.Writer;
      import java.nio.ByteBuffer;
      import java.nio.channels.Channels;
      import java.nio.channels.WritableByteChannel;
      import java.nio.charset.StandardCharsets;

      class Scratch
      {
          public static void main( String[] args )
          {
              ErroringByteChannel channel = new ErroringByteChannel();
              try( Writer writer = Channels.newWriter( channel, StandardCharsets.UTF_8.newEncoder(), -1 ) )
              {
                  writer.write( "Test" );
              }
              catch( IOException e )
              {
                  e.printStackTrace();
              }
          }

          private static class ErroringByteChannel implements WritableByteChannel
          {
              private boolean open = true;

              @Override
              public int write( ByteBuffer src ) throws IOException
              {
                  throw new IOException();
              }

              @Override
              public boolean isOpen()
              {
                  return open;
              }

              @Override
              public void close()
              {
                  open = false;
                  System.out.println( "Closing" );
              }
          }
      }

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

      Attachments

        Activity

          People

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

            Dates

              Created:
              Updated:
              Resolved: