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

DeflaterInput/OutputStream and InflaterInput/OutputStream should explain responsibility for freeing resources

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P5 P5
    • 25
    • core-libs
    • None
    • behavioral
    • minimal
    • The changes update the specification to match the current implementation in these classes. The chances of this change causing a compatibility impact are thus minimal.
    • Java API
    • SE

      Summary

      The specification of java.util.zip.DeflaterOutputStream, java.util.zip.DeflaterInputStream, java.util.zip.InflaterInputStream and java.util.zip.InflaterOutputStream classes will be enhanced to specify the usage and closure of java.util.zip.Deflater and java.util.zip.Inflater instances by these classes.

      Problem

      The implementation of DeflaterOutputStream and DeflaterInputStream uses Deflater instance to compress the stream data. Each of these classes have more than one constructor to construct the stream. Some of these constructors allow application code to pass a Deflater instance whereas some other constructors do not accept a Deflater and instead create a Deflater instance of their own. When the stream is closed, the current implementation of these classes close the Deflater instance if the stream was constructed without being passed a Deflater. On the other hand, if a Deflater was passed during construction of the stream, the application code is expected to close that Deflater instance after the stream has been closed.

      Similar implementation resides in InflaterOutputStream and InflaterInputStream classes which can be constructed either by passing a Inflater or the Inflater being created by the stream during construction.

      Neither of these classes specify that the application code needs to take responsibility of closing the Deflater/Inflater instance if the stream was constructed by passing it the Deflater/Inflater.

      Solution

      The specification of these 4 classes will be updated to match the current implementation and clarify the responsibility of the application code when dealing with the Deflater/Inflater instance.

      Specification

      diff --git a/src/java.base/share/classes/java/util/zip/DeflaterInputStream.java b/src/java.base/share/classes/java/util/zip/DeflaterInputStream.java
      + * <h2 id="compressor-usage">Compressor Usage</h2>
      + * A {@code DeflaterInputStream} created without
      + * specifying a {@linkplain Deflater compressor} will create a compressor
      + * at construction time, and close the compressor when the input stream
      + * is {@linkplain #close closed}.
      + * <p>
      + * If a compressor is specified when creating a {@code DeflaterInputStream}, it is the
      + * responsibility of the caller to {@linkplain Deflater#close close} the
      + * compressor after closing the input stream.
      + *
      + * @apiNote
      + * The {@link #close} method should be called to release resources used by this
      + * stream, either directly, or with the {@code try}-with-resources statement.
      + *
      @@ -68,8 +82,11 @@ private void ensureOpen() throws IOException {
           }
      
           /**
      -     * Creates a new input stream with a default compressor and buffer
      -     * size.
      +     * Creates a new input stream and compressor with the
      +     * default compression level and a default buffer size.
      +     * <p>
      +     * The compressor will be closed when this input stream
      +     * is {@linkplain #close() closed}.
            *
            * @param in input stream to read the uncompressed data to
            * @throws NullPointerException if {@code in} is null
      @@ -82,6 +99,10 @@ public DeflaterInputStream(InputStream in) {
           /**
            * Creates a new input stream with the specified compressor and a
            * default buffer size.
      +     * <p>
      +     * {@linkplain #close() Closing} this input stream
      +     * {@linkplain ##compressor-usage will not close} the given
      +     * {@linkplain Deflater compressor}.
            *
            * @param in input stream to read the uncompressed data to
            * @param defl compressor ("deflater") for this stream
      @@ -94,6 +115,10 @@ public DeflaterInputStream(InputStream in, Deflater defl) {
           /**
            * Creates a new input stream with the specified compressor and buffer
            * size.
      +     * <p>
      +     * {@linkplain #close() Closing} this input stream
      +     * {@linkplain ##compressor-usage will not close} the given
      +     * {@linkplain Deflater compressor}.
            *
            * @param in input stream to read the uncompressed data to
            * @param defl compressor ("deflater") for this stream
      @@ -123,6 +148,7 @@ public DeflaterInputStream(InputStream in, Deflater defl, int bufLen) {
      
      diff --git a/src/java.base/share/classes/java/util/zip/DeflaterOutputStream.java b/src/java.base/share/classes/java/util/zip/DeflaterOutputStream.java
      + * <h2 id="compressor-usage">Compressor Usage</h2>
      + * A {@code DeflaterOutputStream} created without
      + * specifying a {@linkplain Deflater compressor} will create a compressor
      + * at construction time, and close the compressor when the output stream
      + * is {@linkplain #close closed}.
      + * <p>
      + * If a compressor is specified when creating a {@code DeflaterOutputStream}, it is the
      + * responsibility of the caller to {@linkplain Deflater#close close} the
      + * compressor after closing the output stream.
      + *
      + * @apiNote
      + * The {@link #close} method should be called to release resources used by this
      + * stream, either directly, or with the {@code try}-with-resources statement.
      + *
      @@ -63,6 +77,10 @@ public class DeflaterOutputStream extends FilterOutputStream {
           /**
            * Creates a new output stream with the specified compressor,
            * buffer size and flush mode.
      +     * <p>
      +     * {@linkplain #close() Closing} this output stream
      +     * {@linkplain ##compressor-usage will not close} the given
      +     * {@linkplain Deflater compressor}.
            *
            * @param out the output stream
            * @param def the compressor ("deflater")
      @@ -98,7 +116,11 @@ public DeflaterOutputStream(OutputStream out,
            * buffer size.
            *
            * <p>The new output stream instance is created as if by invoking
      -     * the 4-argument constructor DeflaterOutputStream(out, def, size, false).
      +     * the 4-argument constructor {@code DeflaterOutputStream(out, def, size, false)}.
      +     * <p>
      +     * {@linkplain #close() Closing} this output stream
      +     * {@linkplain ##compressor-usage will not close} the given
      +     * {@linkplain Deflater compressor}.
            *
            * @param out the output stream
            * @param def the compressor ("deflater")
      @@ -112,6 +134,10 @@ public DeflaterOutputStream(OutputStream out, Deflater def, int size) {
           /**
            * Creates a new output stream with the specified compressor, flush
            * mode and a default buffer size.
      +     * <p>
      +     * {@linkplain #close() Closing} this output stream
      +     * {@linkplain ##compressor-usage will not close} the given
      +     * {@linkplain Deflater compressor}.
            *
            * @param out the output stream
            * @param def the compressor ("deflater")
      @@ -135,7 +161,11 @@ public DeflaterOutputStream(OutputStream out,
            * a default buffer size.
            *
            * <p>The new output stream instance is created as if by invoking
      -     * the 3-argument constructor DeflaterOutputStream(out, def, false).
      +     * the 3-argument constructor {@code DeflaterOutputStream(out, def, false)}.
      +     * <p>
      +     * {@linkplain #close() Closing} this output stream
      +     * {@linkplain ##compressor-usage will not close} the given
      +     * {@linkplain Deflater compressor}.
            *
            * @param out the output stream
            * @param def the compressor ("deflater")
      @@ -148,8 +178,12 @@ public DeflaterOutputStream(OutputStream out, Deflater def) {
      
      
           /**
      -     * Creates a new output stream with a default compressor, a default
      -     * buffer size and the specified flush mode.
      +     * Creates a new output stream and compressor with the
      +     * default compression level, a default buffer size and
      +     * the specified flush mode.
      +     * <p>
      +     * The compressor will be closed when this output stream
      +     * is {@linkplain #close() closed}.
            *
            * @param out the output stream
            * @param syncFlush
      @@ -166,10 +200,14 @@ public DeflaterOutputStream(OutputStream out, boolean syncFlush) {
           }
      
           /**
      -     * Creates a new output stream with a default compressor and buffer size.
      +     * Creates a new output stream and compressor with the
      +     * default compression level and a default buffer size.
            *
            * <p>The new output stream instance is created as if by invoking
      -     * the 2-argument constructor DeflaterOutputStream(out, false).
      +     * the 2-argument constructor {@code DeflaterOutputStream(out, false)}.
      +     * <p>
      +     * The compressor will be closed when this output stream
      +     * is {@linkplain #close() closed}.
            *
            * @param out the output stream
            */
      @@ -184,6 +222,7 @@ public DeflaterOutputStream(OutputStream out) {
      
      diff --git a/src/java.base/share/classes/java/util/zip/InflaterInputStream.java b/src/java.base/share/classes/java/util/zip/InflaterInputStream.java
      + *
      + * <h2 id="decompressor-usage">Decompressor Usage</h2>
      + * An {@code InflaterInputStream} created without
      + * specifying a {@linkplain Inflater decompressor} will create a decompressor
      + * at construction time, and close the decompressor when the input stream
      + * is {@linkplain #close closed}.
      + * <p>
      + * If a decompressor is specified when creating a {@code InflaterInputStream}, it is the
      + * responsibility of the caller to {@linkplain Inflater#close close} the
      + * decompressor after closing the input stream.
      + *
      + * @apiNote
      + * The {@link #close} method should be called to release resources used by this
      + * stream, either directly, or with the {@code try}-with-resources statement.
      + *
           /**
            * Creates a new input stream with the specified decompressor and
            * buffer size.
      +     * <p>
      +     * {@linkplain #close() Closing} this input stream
      +     * {@linkplain ##decompressor-usage will not close} the given
      +     * {@linkplain Inflater decompressor}.
      +     *
            * @param in the input stream
            * @param inf the decompressor ("inflater")
            * @param size the input buffer size
      @@ -94,6 +114,11 @@ public InflaterInputStream(InputStream in, Inflater inf, int size) {
           /**
            * Creates a new input stream with the specified decompressor and a
            * default buffer size.
      +     * <p>
      +     * {@linkplain #close() Closing} this input stream
      +     * {@linkplain ##decompressor-usage will not close} the given
      +     * {@linkplain Inflater decompressor}.
      +     *
            * @param in the input stream
            * @param inf the decompressor ("inflater")
            */
      @@ -104,7 +129,12 @@ public InflaterInputStream(InputStream in, Inflater inf) {
           boolean usesDefaultInflater = false;
      
           /**
      -     * Creates a new input stream with a default decompressor and buffer size.
      +     * Creates a new input stream and decompressor with a
      +     * default buffer size.
      +     * <p>
      +     * The decompressor will be closed when this input stream
      +     * is {@linkplain #close() closed}.
      +     *
            * @param in the input stream
            */
           public InflaterInputStream(InputStream in) {
      @@ -120,6 +150,7 @@ public InflaterInputStream(InputStream in) {
      
      diff --git a/src/java.base/share/classes/java/util/zip/InflaterOutputStream.java b/src/java.base/share/classes/java/util/zip/InflaterOutputStream.java
      + * <h2 id="decompressor-usage">Decompressor Usage</h2>
      + * An {@code InflaterOutputStream} created without
      + * specifying a {@linkplain Inflater decompressor} will create a decompressor
      + * at construction time, and close the decompressor when the output stream
      + * is {@linkplain #close closed}.
      + * <p>
      + * If a decompressor is specified when creating a {@code InflaterOutputStream}, it is the
      + * responsibility of the caller to {@linkplain Inflater#close close} the
      + * decompressor after closing the output stream.
      + *
      + * @apiNote
      + * The {@link #close} method should be called to release resources used by this
      + * stream, either directly, or with the {@code try}-with-resources statement.
      + *
           /**
      -     * Creates a new output stream with a default decompressor and buffer
      -     * size.
      +     * Creates a new output stream and decompressor with a
      +     * default buffer size.
      +     * <p>
      +     * The decompressor will be closed when this output stream
      +     * is {@linkplain #close() closed}.
            *
            * @param out output stream to write the uncompressed data to
            * @throws NullPointerException if {@code out} is null
      @@ -82,6 +99,10 @@ public InflaterOutputStream(OutputStream out) {
           /**
            * Creates a new output stream with the specified decompressor and a
            * default buffer size.
      +     * <p>
      +     * {@linkplain #close() Closing} this output stream
      +     * {@linkplain ##decompressor-usage will not close} the given
      +     * {@linkplain Inflater decompressor}.
            *
            * @param out output stream to write the uncompressed data to
            * @param infl decompressor ("inflater") for this stream
      @@ -94,6 +115,10 @@ public InflaterOutputStream(OutputStream out, Inflater infl) {
           /**
            * Creates a new output stream with the specified decompressor and
            * buffer size.
      +     * <p>
      +     * {@linkplain #close() Closing} this output stream
      +     * {@linkplain ##decompressor-usage will not close} the given
      +     * {@linkplain Inflater decompressor}.
            *
            * @param out output stream to write the uncompressed data to
            * @param infl decompressor ("inflater") for this stream
      @@ -123,6 +148,7 @@ public InflaterOutputStream(OutputStream out, Inflater infl, int bufLen) {

            jpai Jaikiran Pai
            hannesw Hannes Wallnoefer
            Alan Bateman, Chen Liang, Lance Andersen
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: