From eba4aeffc5184cefcca7799990e64cd91e8b75b6 Mon Sep 17 00:00:00 2001 From: prrace Date: Tue, 5 Aug 2025 14:09:33 -0700 Subject: [PATCH 1/4] 8277585 --- .../plugins/common/SubImageInputStream.java | 6 -- .../imageio/plugins/png/PNGImageWriter.java | 14 ---- .../sun/imageio/stream/StreamFinalizer.java | 73 ------------------- .../stream/FileCacheImageInputStream.java | 25 +------ .../stream/FileCacheImageOutputStream.java | 43 ++++++++++- .../imageio/stream/FileImageInputStream.java | 25 +------ .../imageio/stream/FileImageOutputStream.java | 25 +------ .../imageio/stream/ImageInputStreamImpl.java | 25 ------- .../stream/MemoryCacheImageInputStream.java | 25 +------ .../javax/imageio/stream/package-info.java | 26 ++++++- 10 files changed, 74 insertions(+), 213 deletions(-) delete mode 100644 src/java.desktop/share/classes/com/sun/imageio/stream/StreamFinalizer.java diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/common/SubImageInputStream.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/common/SubImageInputStream.java index 10211c6636c90..5d6bd401dc65c 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/common/SubImageInputStream.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/common/SubImageInputStream.java @@ -71,10 +71,4 @@ public void seek(long pos) throws IOException { stream.seek(pos - startingPos); streamPos = pos; } - - @SuppressWarnings("removal") - protected void finalize() throws Throwable { - // Empty finalizer (for improved performance; no need to call - // super.finalize() in this case) - } } diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java index 38f8829bae1f0..b88574edd6e58 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java @@ -146,13 +146,6 @@ void finish() throws IOException { stream.seek(pos); stream.flushBefore(pos); } - - @Override - @SuppressWarnings("removal") - protected void finalize() throws Throwable { - // Empty finalizer (for improved performance; no need to call - // super.finalize() in this case) - } } // Compress output and write as a series of 'IDAT' chunks of @@ -283,13 +276,6 @@ void finish() throws IOException { def.end(); } } - - @Override - @SuppressWarnings("removal") - protected void finalize() throws Throwable { - // Empty finalizer (for improved performance; no need to call - // super.finalize() in this case) - } } diff --git a/src/java.desktop/share/classes/com/sun/imageio/stream/StreamFinalizer.java b/src/java.desktop/share/classes/com/sun/imageio/stream/StreamFinalizer.java deleted file mode 100644 index 012d7e1064598..0000000000000 --- a/src/java.desktop/share/classes/com/sun/imageio/stream/StreamFinalizer.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.imageio.stream; - -import java.io.IOException; -import javax.imageio.stream.ImageInputStream; - -/** - * Small class to assist in properly closing an ImageInputStream instance - * prior to garbage collection. The ImageInputStreamImpl class defines a - * finalize() method, but in a number of its public subclasses - * (e.g. FileImageInputStream) we override the finalize() method to be - * empty for performance reasons, and instead rely on the Disposer mechanism - * for closing/disposing resources. This is fine when one of these classes - * is instantiated directly (e.g. new FileImageInputStream()) but in the - * unlikely case where a user defines their own subclass of one of those - * streams, we need some way to get back to the behavior of - * ImageInputStreamImpl, which will call close() as part of finalization. - * - * Typically an Image{Input,Output}Stream will construct an instance of - * StreamFinalizer in its constructor if it detects that it has been - * subclassed by the user. The ImageInputStream instance will hold a - * reference to the StreamFinalizer, and the StreamFinalizer will hold a - * reference back to the ImageInputStream from which it was created. When - * both are no longer reachable, the StreamFinalizer.finalize() method will - * be called, which will take care of closing down the ImageInputStream. - * - * Clearly this is a bit of a hack, but it will likely only be used in the - * rarest of circumstances: when a user has subclassed one of the public - * stream classes. (It should be no worse than the old days when the public - * stream classes had non-empty finalize() methods.) - */ -public class StreamFinalizer { - private ImageInputStream stream; - - public StreamFinalizer(ImageInputStream stream) { - this.stream = stream; - } - - @SuppressWarnings("removal") - protected void finalize() throws Throwable { - try { - stream.close(); - } catch (IOException e) { - } finally { - stream = null; - super.finalize(); - } - } -} diff --git a/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageInputStream.java b/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageInputStream.java index d5c1ff18e5a68..0133bc13da7b9 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageInputStream.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageInputStream.java @@ -31,7 +31,6 @@ import java.io.RandomAccessFile; import java.nio.file.Files; import com.sun.imageio.stream.StreamCloser; -import com.sun.imageio.stream.StreamFinalizer; import sun.java2d.Disposer; import sun.java2d.DisposerRecord; @@ -58,7 +57,7 @@ public class FileCacheImageInputStream extends ImageInputStreamImpl { private boolean foundEOF = false; /** The referent to be registered with the Disposer. */ - private final Object disposerReferent; + private final Object disposerReferent = new Object(); /** The DisposerRecord that closes the underlying cache. */ private final DisposerRecord disposerRecord; @@ -109,12 +108,7 @@ public FileCacheImageInputStream(InputStream stream, File cacheDir) StreamCloser.addToQueue(closeAction); disposerRecord = new StreamDisposerRecord(cacheFile, cache); - if (getClass() == FileCacheImageInputStream.class) { - disposerReferent = new Object(); - Disposer.addRecord(disposerReferent, disposerRecord); - } else { - disposerReferent = new StreamFinalizer(this); - } + Disposer.addRecord(disposerReferent, disposerRecord); } /** @@ -258,21 +252,6 @@ public void close() throws IOException { StreamCloser.removeFromQueue(closeAction); } - /** - * {@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 { - // Empty finalizer: for performance reasons we instead use the - // Disposer mechanism for ensuring that the underlying - // RandomAccessFile is closed/deleted prior to garbage collection - } - private static class StreamDisposerRecord implements DisposerRecord { private File cacheFile; private RandomAccessFile cache; diff --git a/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java b/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java index 5886831d6e990..b501081161f88 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java @@ -31,6 +31,8 @@ import java.io.RandomAccessFile; import java.nio.file.Files; import com.sun.imageio.stream.StreamCloser; +import sun.java2d.Disposer; +import sun.java2d.DisposerRecord; /** * An implementation of {@code ImageOutputStream} that writes its @@ -46,6 +48,9 @@ public class FileCacheImageOutputStream extends ImageOutputStreamImpl { private RandomAccessFile cache; + private final Object disposerReferent = new Object(); + + private final FileCacheDisposerRecord disposerRecord; // Pos after last (rightmost) byte written private long maxStreamPos = 0L; @@ -91,6 +96,13 @@ public FileCacheImageOutputStream(OutputStream stream, File cacheDir) .toFile(); this.cache = new RandomAccessFile(cacheFile, "rw"); + // If this instance becomes unreachable the disposer will clean up resources + // used for caching. This can't flush any un-flushed cache. + this.disposerRecord = new FileCacheDisposerRecord(cacheFile, cache); + Disposer.addRecord(this.disposerReferent, this.disposerRecord); + // If the VM is exiting and this instance is still reachable, + // StreamCloser will call close() to flush the cache and clean up resources. + // However closing the java.io.OutputStream is the application's responsibility. this.closeAction = StreamCloser.createCloseAction(this); StreamCloser.addToQueue(closeAction); } @@ -217,6 +229,32 @@ public boolean isCachedMemory() { return false; } + private static class FileCacheDisposerRecord implements DisposerRecord { + + private final File cacheFile; + private final RandomAccessFile cache; + private volatile boolean disposed; + + public FileCacheDisposerRecord(File cacheFile, RandomAccessFile cache) { + this.cacheFile = cacheFile; + this.cache = cache; + } + + @Override + public synchronized void dispose() { + if (disposed) { + return; + } + try { + cache.close(); + cacheFile.delete(); + } catch (IOException e) { + } finally { + disposed = true; + } + } + } + /** * Closes this {@code FileCacheImageOutputStream}. All * pending data is flushed to the output, and the cache file @@ -231,9 +269,10 @@ public void close() throws IOException { seek(maxStreamPos); flushBefore(maxStreamPos); super.close(); - cache.close(); + disposerRecord.dispose(); + //cache.close(); cache = null; - cacheFile.delete(); + //cacheFile.delete(); cacheFile = null; stream.flush(); stream = null; diff --git a/src/java.desktop/share/classes/javax/imageio/stream/FileImageInputStream.java b/src/java.desktop/share/classes/javax/imageio/stream/FileImageInputStream.java index 98b444b31863f..e5baee6e7c096 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/FileImageInputStream.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/FileImageInputStream.java @@ -30,7 +30,6 @@ import java.io.IOException; import java.io.RandomAccessFile; import com.sun.imageio.stream.CloseableDisposerRecord; -import com.sun.imageio.stream.StreamFinalizer; import sun.java2d.Disposer; /** @@ -45,7 +44,7 @@ public class FileImageInputStream extends ImageInputStreamImpl { private RandomAccessFile raf; /** The referent to be registered with the Disposer. */ - private final Object disposerReferent; + private final Object disposerReferent = new Object(); /** The DisposerRecord that closes the underlying RandomAccessFile. */ private final CloseableDisposerRecord disposerRecord; @@ -95,12 +94,7 @@ public FileImageInputStream(RandomAccessFile raf) { } disposerRecord = new CloseableDisposerRecord(raf); - if (getClass() == FileImageInputStream.class) { - disposerReferent = new Object(); - Disposer.addRecord(disposerReferent, disposerRecord); - } else { - disposerReferent = new StreamFinalizer(this); - } + Disposer.addRecord(disposerReferent, disposerRecord); } public int read() throws IOException { @@ -154,19 +148,4 @@ public void close() throws IOException { disposerRecord.dispose(); // this closes the RandomAccessFile raf = null; } - - /** - * {@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 { - // Empty finalizer: for performance reasons we instead use the - // Disposer mechanism for ensuring that the underlying - // RandomAccessFile is closed prior to garbage collection - } } diff --git a/src/java.desktop/share/classes/javax/imageio/stream/FileImageOutputStream.java b/src/java.desktop/share/classes/javax/imageio/stream/FileImageOutputStream.java index 6597f137dcfe3..8a22afd5b1228 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/FileImageOutputStream.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/FileImageOutputStream.java @@ -30,7 +30,6 @@ import java.io.IOException; import java.io.RandomAccessFile; import com.sun.imageio.stream.CloseableDisposerRecord; -import com.sun.imageio.stream.StreamFinalizer; import sun.java2d.Disposer; /** @@ -44,7 +43,7 @@ public class FileImageOutputStream extends ImageOutputStreamImpl { private RandomAccessFile raf; /** The referent to be registered with the Disposer. */ - private final Object disposerReferent; + private final Object disposerReferent = new Object(); /** The DisposerRecord that closes the underlying RandomAccessFile. */ private final CloseableDisposerRecord disposerRecord; @@ -87,12 +86,7 @@ public FileImageOutputStream(RandomAccessFile raf) { } disposerRecord = new CloseableDisposerRecord(raf); - if (getClass() == FileImageOutputStream.class) { - disposerReferent = new Object(); - Disposer.addRecord(disposerReferent, disposerRecord); - } else { - disposerReferent = new StreamFinalizer(this); - } + Disposer.addRecord(disposerReferent, disposerRecord); } public int read() throws IOException { @@ -162,19 +156,4 @@ public void close() throws IOException { disposerRecord.dispose(); // this closes the RandomAccessFile raf = null; } - - /** - * {@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 { - // Empty finalizer: for performance reasons we instead use the - // Disposer mechanism for ensuring that the underlying - // RandomAccessFile is closed prior to garbage collection - } } diff --git a/src/java.desktop/share/classes/javax/imageio/stream/ImageInputStreamImpl.java b/src/java.desktop/share/classes/javax/imageio/stream/ImageInputStreamImpl.java index a6feaa45d47a1..f21f9ec5ade0a 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/ImageInputStreamImpl.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/ImageInputStreamImpl.java @@ -841,29 +841,4 @@ public void close() throws IOException { isClosed = true; } - - /** - * 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 { - if (!isClosed) { - try { - close(); - } catch (IOException e) { - } - } - super.finalize(); - } } diff --git a/src/java.desktop/share/classes/javax/imageio/stream/MemoryCacheImageInputStream.java b/src/java.desktop/share/classes/javax/imageio/stream/MemoryCacheImageInputStream.java index ecb30ddba5205..1799254c59ae9 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/MemoryCacheImageInputStream.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/MemoryCacheImageInputStream.java @@ -27,7 +27,6 @@ import java.io.InputStream; import java.io.IOException; -import com.sun.imageio.stream.StreamFinalizer; import sun.java2d.Disposer; import sun.java2d.DisposerRecord; @@ -50,7 +49,7 @@ public class MemoryCacheImageInputStream extends ImageInputStreamImpl { private MemoryCache cache = new MemoryCache(); /** The referent to be registered with the Disposer. */ - private final Object disposerReferent; + private final Object disposerReferent = new Object(); /** The DisposerRecord that resets the underlying MemoryCache. */ private final DisposerRecord disposerRecord; @@ -71,12 +70,7 @@ public MemoryCacheImageInputStream(InputStream stream) { this.stream = stream; disposerRecord = new StreamDisposerRecord(cache); - if (getClass() == MemoryCacheImageInputStream.class) { - disposerReferent = new Object(); - Disposer.addRecord(disposerReferent, disposerRecord); - } else { - disposerReferent = new StreamFinalizer(this); - } + Disposer.addRecord(disposerReferent, disposerRecord); } public int read() throws IOException { @@ -176,21 +170,6 @@ public void close() throws IOException { cache = null; } - /** - * {@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 { - // Empty finalizer: for performance reasons we instead use the - // Disposer mechanism for ensuring that the underlying - // MemoryCache is reset prior to garbage collection - } - private static class StreamDisposerRecord implements DisposerRecord { private MemoryCache cache; diff --git a/src/java.desktop/share/classes/javax/imageio/stream/package-info.java b/src/java.desktop/share/classes/javax/imageio/stream/package-info.java index b28caf0ef0d7d..4de18c6254ec9 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/package-info.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/package-info.java @@ -44,7 +44,31 @@ *

* The {@code IIOByteBuffer} class provides an alternative way to perform reads * of sequences of bytes that reduces the amount of internal data copying. - * + *

+ * An {@code ImageInputStream} or {@code ImageInputStream} 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 + * } + *

+ * 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. * @since 1.4 */ package javax.imageio.stream; From edbbbd4fa49220a1e407fe2cb484035eee42b0ce Mon Sep 17 00:00:00 2001 From: prrace Date: Tue, 5 Aug 2025 14:21:56 -0700 Subject: [PATCH 2/4] 8277585 --- .../javax/imageio/stream/FileCacheImageOutputStream.java | 8 ++++---- .../share/classes/javax/imageio/stream/package-info.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java b/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java index b501081161f88..596a0c477e8b5 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java @@ -233,7 +233,7 @@ private static class FileCacheDisposerRecord implements DisposerRecord { private final File cacheFile; private final RandomAccessFile cache; - private volatile boolean disposed; + private volatile boolean disposed; public FileCacheDisposerRecord(File cacheFile, RandomAccessFile cache) { this.cacheFile = cacheFile; @@ -246,15 +246,15 @@ public synchronized void dispose() { return; } try { - cache.close(); - cacheFile.delete(); + cache.close(); + cacheFile.delete(); } catch (IOException e) { } finally { disposed = true; } } } - + /** * Closes this {@code FileCacheImageOutputStream}. All * pending data is flushed to the output, and the cache file diff --git a/src/java.desktop/share/classes/javax/imageio/stream/package-info.java b/src/java.desktop/share/classes/javax/imageio/stream/package-info.java index 4de18c6254ec9..7cf59c8954cc0 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/package-info.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/package-info.java @@ -47,7 +47,7 @@ *

* An {@code ImageInputStream} or {@code ImageInputStream} may internally allocate * system resources, such as a temporary cache file. - * Clients are encouraged to use a try-with-resources statement to ensure the + * 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 From 8aabb9d809cc1ba5d9ef1982917b12de7188b8c9 Mon Sep 17 00:00:00 2001 From: prrace Date: Wed, 6 Aug 2025 12:37:22 -0700 Subject: [PATCH 3/4] 8277585 --- .../javax/imageio/stream/FileCacheImageOutputStream.java | 2 -- .../share/classes/javax/imageio/stream/package-info.java | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java b/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java index 596a0c477e8b5..d56f3eb888cae 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java @@ -270,9 +270,7 @@ public void close() throws IOException { flushBefore(maxStreamPos); super.close(); disposerRecord.dispose(); - //cache.close(); cache = null; - //cacheFile.delete(); cacheFile = null; stream.flush(); stream = null; diff --git a/src/java.desktop/share/classes/javax/imageio/stream/package-info.java b/src/java.desktop/share/classes/javax/imageio/stream/package-info.java index 7cf59c8954cc0..0b0e5e366a369 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/package-info.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/package-info.java @@ -45,7 +45,7 @@ * The {@code IIOByteBuffer} class provides an alternative way to perform reads * of sequences of bytes that reduces the amount of internal data copying. *

- * An {@code ImageInputStream} or {@code ImageInputStream} may internally allocate + * 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()} From 7d42251360729690fa4bf5234ae8e749116c359f Mon Sep 17 00:00:00 2001 From: prrace Date: Wed, 6 Aug 2025 15:31:18 -0700 Subject: [PATCH 4/4] 8277585 --- .../stream/FileCacheImageInputStream.java | 2 +- .../stream/FileCacheImageOutputStream.java | 31 ++----------------- .../javax/imageio/stream/package-info.java | 4 +-- 3 files changed, 6 insertions(+), 31 deletions(-) diff --git a/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageInputStream.java b/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageInputStream.java index 0133bc13da7b9..4f44ad1ab2a33 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageInputStream.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageInputStream.java @@ -252,7 +252,7 @@ public void close() throws IOException { StreamCloser.removeFromQueue(closeAction); } - private static class StreamDisposerRecord implements DisposerRecord { + static class StreamDisposerRecord implements DisposerRecord { private File cacheFile; private RandomAccessFile cache; diff --git a/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java b/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java index d56f3eb888cae..13269832ab5fb 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java @@ -30,6 +30,7 @@ import java.io.OutputStream; import java.io.RandomAccessFile; import java.nio.file.Files; +import javax.imageio.stream.FileCacheImageInputStream.StreamDisposerRecord; import com.sun.imageio.stream.StreamCloser; import sun.java2d.Disposer; import sun.java2d.DisposerRecord; @@ -50,7 +51,7 @@ public class FileCacheImageOutputStream extends ImageOutputStreamImpl { private final Object disposerReferent = new Object(); - private final FileCacheDisposerRecord disposerRecord; + private final StreamDisposerRecord disposerRecord; // Pos after last (rightmost) byte written private long maxStreamPos = 0L; @@ -98,7 +99,7 @@ public FileCacheImageOutputStream(OutputStream stream, File cacheDir) // If this instance becomes unreachable the disposer will clean up resources // used for caching. This can't flush any un-flushed cache. - this.disposerRecord = new FileCacheDisposerRecord(cacheFile, cache); + this.disposerRecord = new StreamDisposerRecord(cacheFile, cache); Disposer.addRecord(this.disposerReferent, this.disposerRecord); // If the VM is exiting and this instance is still reachable, // StreamCloser will call close() to flush the cache and clean up resources. @@ -229,32 +230,6 @@ public boolean isCachedMemory() { return false; } - private static class FileCacheDisposerRecord implements DisposerRecord { - - private final File cacheFile; - private final RandomAccessFile cache; - private volatile boolean disposed; - - public FileCacheDisposerRecord(File cacheFile, RandomAccessFile cache) { - this.cacheFile = cacheFile; - this.cache = cache; - } - - @Override - public synchronized void dispose() { - if (disposed) { - return; - } - try { - cache.close(); - cacheFile.delete(); - } catch (IOException e) { - } finally { - disposed = true; - } - } - } - /** * Closes this {@code FileCacheImageOutputStream}. All * pending data is flushed to the output, and the cache file diff --git a/src/java.desktop/share/classes/javax/imageio/stream/package-info.java b/src/java.desktop/share/classes/javax/imageio/stream/package-info.java index 0b0e5e366a369..56dccaa9823b6 100644 --- a/src/java.desktop/share/classes/javax/imageio/stream/package-info.java +++ b/src/java.desktop/share/classes/javax/imageio/stream/package-info.java @@ -57,13 +57,13 @@ * A simple pattern would be * {@snippet lang='java': * try (FileOutputStream fos = new FileOutputStream("out.jpg"); - * (ImageOutputStream ios = new FileCacheImageOutputStream(fos, null)) { + * 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 * } *

- * Sub-classers of these Image I/O API stream types can to a limited extent protect + * 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.