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

Default charset for PrintWriter that wraps PrintStream

    XMLWordPrintable

    Details

    • Type: CSR
    • Status: Closed
    • Priority: P3
    • Resolution: Approved
    • Fix Version/s: 18
    • Component/s: core-libs
    • Labels:
      None
    • Subcomponent:
    • Compatibility Kind:
      behavioral
    • Compatibility Risk:
      low
    • Compatibility Risk Description:
      Hide
      The proposed change significantly reduces the compatibility risk and behavior change for cases where PrintStream are wrapped with a writer. There remains a risk that there are other classes that wrap PrintStream and assume its encoding. This risk goes back to JDK 1.0/1.1 but could potentially be observed due to the change to use UTF-8 as the default charset.
      Show
      The proposed change significantly reduces the compatibility risk and behavior change for cases where PrintStream are wrapped with a writer. There remains a risk that there are other classes that wrap PrintStream and assume its encoding. This risk goes back to JDK 1.0/1.1 but could potentially be observed due to the change to use UTF-8 as the default charset.
    • Interface Kind:
      Java API
    • Scope:
      SE

      Description

      Summary

      java.io.PrintWriter should inherit the charset if its OutputStream is an instance of PrintStream.

      Problem

      PrintWriter, also OutputStreamWriter wraps an OutputStream, encoding the incoming stream into char stream. The charset used for encoding is either an explicitly specified one or the default charset. However, this can cause an encoding problem if the wrapped OutputStream is a PrintStream which has its own charset and can differ. With the JEP 400, this problem can arise even with the out-of-the-box environment.

      Solution

      Provide a new public method to retrieve the charset in java.io.PrintStream class so that Print/OutputStreamWriter constructors that take OutputStream can inherit the charset if the output stream is a PrintStream.

      Specification

      Create the following public method in java.io.PrintStream class:

      /**
       * {@return the charset used in this {@code PrintStream} instance}
       *
       * @since 18
       */
      public Charset charset()

      Change the constructor of OutputStreamWriter that takes OutputStream without explicit encoding as follows:

           /**
      -     * Creates an OutputStreamWriter that uses the default character encoding.
      +     * Creates an OutputStreamWriter that uses the default character encoding, or
      +     * where {@code out} is a {@code PrintStream}, the charset used by the print
      +     * stream.
            *
            * @param  out  An OutputStream
            * @see Charset#defaultCharset()
            */
           public OutputStreamWriter(OutputStream out) {

      Change the constructors of PrintStream that take OutputStream without explicit encoding as follows:

      @@ -122,11 +124,12 @@
           }
      
           /**
            * Creates a new print stream, without automatic line flushing, with the
            * specified OutputStream. Characters written to the stream are converted
      -     * to bytes using the default charset.
      +     * to bytes using the default charset, or where {@code out} is a
      +     * {@code PrintStream}, the charset used by the print stream.
            *
            * @param  out        The output stream to which values and objects will be
            *                    printed
            *
            * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream)
            * @see Charset#defaultCharset()
            */
           public PrintStream(OutputStream out) {
      
      @@ -137,10 +140,11 @@
           }
      
           /**
            * Creates a new print stream, with the specified OutputStream and line
            * flushing. Characters written to the stream are converted to bytes using
      -     * the default charset.
      +     * the default charset, or where {@code out} is a {@code PrintStream},
      +     * the charset used by the print stream.
            *
            * @param  out        The output stream to which values and objects will be
            *                    printed
            * @param  autoFlush  Whether the output buffer will be flushed
            *                    whenever a byte array is written, one of the
            *                    {@code println} methods is invoked, or a newline
            *                    character or byte ({@code '\n'}) is written
            *
            * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
            * @see Charset#defaultCharset()
            */
           public PrintStream(OutputStream out, boolean autoFlush) {

      Change the constructors of PrintWriter that take OutputStream without explicit encoding as follows:

      @@ -116,11 +116,12 @@
      
           /**
            * Creates a new PrintWriter, without automatic line flushing, from an
            * existing OutputStream.  This convenience constructor creates the
            * necessary intermediate OutputStreamWriter, which will convert characters
      -     * into bytes using the default charset.
      +     * into bytes using the default charset, or where {@code out} is a
      +     * {@code PrintStream}, the charset used by the print stream.
            *
            * @param  out        An output stream
            *
            * @see OutputStreamWriter#OutputStreamWriter(OutputStream)
            * @see Charset#defaultCharset()
            */
           public PrintWriter(OutputStream out) {
      
      @@ -130,23 +131,24 @@
           }
      
           /**
            * Creates a new PrintWriter from an existing OutputStream.  This
            * convenience constructor creates the necessary intermediate
      -     * OutputStreamWriter, which will convert characters into bytes using the
      -     * default charset.
      +     * OutputStreamWriter, which will convert characters into bytes using
      +     * the default charset, or where {@code out} is a {@code PrintStream},
      +     * the charset used by the print stream.
            *
            * @param  out        An output stream
            * @param  autoFlush  A boolean; if true, the {@code println},
            *                    {@code printf}, or {@code format} methods will
            *                    flush the output buffer
            *
            * @see OutputStreamWriter#OutputStreamWriter(OutputStream)
            * @see Charset#defaultCharset()
            */
           public PrintWriter(OutputStream out, boolean autoFlush) {

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              naoto Naoto Sato
              Reporter:
              naoto Naoto Sato
              Reviewed By:
              Alan Bateman
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: