-
CSR
-
Resolution: Approved
-
P4
-
behavioral
-
medium
-
-
Java API
-
SE
Summary
finalize() is removed from javax.imageio.ImageInputStreamImpl and its subclasses.
Problem
javax.imageio.stream.ImageInputStreamImpl is the parent class of all the implementations of ImageInputStream and ImageOutputStream in the javax.imageio API and it defines finalize() as a last resort backstop to properly call close() and free internal resources. 3rd party sub-classes which derive from ImageInputStreamImpl may also rely on finalization. However finalization is deprecated for removal by JEP 421 https://openjdk.org/jeps/421.
Solution
To the extent possible, replace finalization with other mechanisms to free resources. Document the requirements on applications to ensure resources are freed.
The principal alternate mechanism is a "cleaner". Not java.lang.ref.Cleaner, but a very similar internal class used in the java.desktop module. And this is in fact already used by most of the concrete javax.imageio.stream classes, and these over-ride finalize() to be empty, thus avoiding finalization. These empty over-rides are now removed (see Specification).
The two classes that still used finalization : javax/imageio/stream/FileCacheImageOutputStream.java and javax/imageio/stream/MemoryCacheImageOutputStream.java
are un-changed in javadoc, because they inherited the ImageInputStreamImpl.java default finalize() method. However the package documentation is now updated to inform applications of the need to call close() and internally a disposer/cleaner will ensure native resources are freed for these JDK classes. See the compatibility risk section for more details.
Specification
javax/imageio/stream/package-info.java
+ * An {@code ImageInputStream} or {@code ImageOutputStream} may internally allocate
+ * system resources, such as a temporary cache file.
+ * Clients are encouraged to use a try-with-resources statement to ensure the
+ * {@link ImageInputStream#close()} or {@link ImageOutputStream#close()}
+ * method is called which can promptly free those native resources.
+ * Otherwise there is the possibility they will leak and eventually cause the
+ * application to fail as well the possibility that not all data is flushed
+ * to the underlying output stream. A logical consequence of that is that
+ * this should be done before closing the destination {@link java.io.OutputStream}.
+ * A simple pattern would be
+ * {@snippet lang='java':
+ * try (FileOutputStream fos = new FileOutputStream("out.jpg");
+ * ImageOutputStream ios = new FileCacheImageOutputStream(fos, null)) {
+ * ImageIO.write(img, "jpg", ios);
+ * } catch (IOException e) {
+ * } // implicit finally block closes the streams in the reverse order to opening
+ * }
+ * <p>
+ * Sub-classers of these Image I/O API stream types can, to a limited extent, protect
+ * the application from the consequences of failures to close by adopting mechanisms
+ * such as {@link java.lang.ref.Cleaner} to free internal resources when it
+ * is no longer reachable. This is only necessary if there are any resources to release.
+ * However applications cannot rely on this, either for resource management, or
+ * for program correctness.
javax/imageio/stream/ImageInputStreamImpl.java - remove finalize from abstract base class.
- /**
- * Finalizes this object prior to garbage collection. The
- * {@code close} method is called to close any open input
- * source. This method should not be called from application
- * code.
- *
- * @throws Throwable if an error occurs during superclass
- * finalization.
- *
- * @deprecated Finalization has been deprecated for removal. See
- * {@link java.lang.Object#finalize} for background information and details
- * about migration options.
- */
- @Deprecated(since="9", forRemoval=true)
- @SuppressWarnings("removal")
- protected void finalize() throws Throwable
javax/imageio/stream/FileCacheImageInputStream.java - remove empty finalize override
- /**
- * {@inheritDoc}
- *
- * @deprecated Finalization has been deprecated for removal. See
- * {@link java.lang.Object#finalize} for background information and details
- * about migration options.
- */
- @Deprecated(since="9", forRemoval=true)
- @SuppressWarnings("removal")
- protected void finalize() throws Throwable
javax/imageio/stream/FileImageInputStream.java - remove empty finalize override
- /**
- * {@inheritDoc}
- *
- * @deprecated Finalization has been deprecated for removal. See
- * {@link java.lang.Object#finalize} for background information and details
- * about migration options.
- */
- @Deprecated(since="9", forRemoval=true)
- @SuppressWarnings("removal")
- protected void finalize() throws Throwable
javax/imageio/stream/FileImageOutputStream.java - remove empty finalize override
- /**
- * {@inheritDoc}
- *
- * @deprecated Finalization has been deprecated for removal. See
- * {@link java.lang.Object#finalize} for background information and details
- * about migration options.
- */
- @Deprecated(since="9", forRemoval=true)
- @SuppressWarnings("removal")
- protected void finalize() throws Throwable
javax/imageio/stream/MemoryCacheImageInputStream.java - remove empty finalize override
- /**
- * {@inheritDoc}
- *
- * @deprecated Finalization has been deprecated for removal. See
- * {@link java.lang.Object#finalize} for background information and details
- * about migration options.
- */
- @Deprecated(since="9", forRemoval=true)
- @SuppressWarnings("removal")
- protected void finalize() throws Throwable
- csr of
-
JDK-8277585 Remove the terminally deprecated finalize() method from javax.imageio.stream APIs
-
- Resolved
-