From b399bcdca38a3f93bf41d9c92253b1813546c3c2 Mon Sep 17 00:00:00 2001 From: prrace Date: Mon, 11 Aug 2025 14:46:07 -0700 Subject: [PATCH 1/3] 8365292 --- .../javax/imageio/spi/ServiceRegistry.java | 30 ++----------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java b/src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java index 3f82cb3d9f78c..4436f89b2c72a 100644 --- a/src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java +++ b/src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java @@ -283,8 +283,7 @@ public boolean registerServiceProvider(T provider, * {@code onRegistration} method will be called once for each * category it is registered under. Its * {@code onDeregistration} method will be called each time - * it is deregistered from a category or when the registry is - * finalized. + * it is deregistered from a category. * * @param provider the service provider object to be registered. * @@ -313,8 +312,7 @@ public void registerServiceProvider(Object provider) { * {@code onRegistration} method will be called once for each * category it is registered under. Its * {@code onDeregistration} method will be called each time - * it is deregistered from a category or when the registry is - * finalized. + * it is deregistered from a category. * * @param providers an Iterator containing service provider * objects to be registered. @@ -667,26 +665,6 @@ public void deregisterAll() { } } - /** - * Finalizes this object prior to garbage collection. The - * {@code deregisterAll} method is called to deregister all - * currently registered service providers. 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") - public void finalize() throws Throwable { - deregisterAll(); - super.finalize(); - } - /** * Checks whether the provided class is one of the allowed * ImageIO service provider classes. If it is, returns normally. @@ -821,10 +799,6 @@ public synchronized void clear() { poset.clear(); } - @SuppressWarnings("removal") - public synchronized void finalize() { - clear(); - } } From 1ba9731d6f1dcca61cdde4aca337451e932f6e8f Mon Sep 17 00:00:00 2001 From: prrace Date: Tue, 12 Aug 2025 12:26:11 -0700 Subject: [PATCH 2/3] 8365292 --- .../javax/imageio/spi/IIORegistry.java | 20 +-- .../javax/imageio/spi/ServiceRegistry.java | 8 +- test/jdk/javax/imageio/AppContextTest.java | 141 ------------------ 3 files changed, 13 insertions(+), 156 deletions(-) delete mode 100644 test/jdk/javax/imageio/AppContextTest.java diff --git a/src/java.desktop/share/classes/javax/imageio/spi/IIORegistry.java b/src/java.desktop/share/classes/javax/imageio/spi/IIORegistry.java index 5286464617aa8..077dbed070cb2 100644 --- a/src/java.desktop/share/classes/javax/imageio/spi/IIORegistry.java +++ b/src/java.desktop/share/classes/javax/imageio/spi/IIORegistry.java @@ -44,7 +44,6 @@ import com.sun.imageio.plugins.wbmp.WBMPImageWriterSpi; import com.sun.imageio.plugins.tiff.TIFFImageReaderSpi; import com.sun.imageio.plugins.tiff.TIFFImageWriterSpi; -import sun.awt.AppContext; import java.util.List; import java.util.ServiceLoader; import java.util.ServiceConfigurationError; @@ -105,25 +104,18 @@ private IIORegistry() { registerApplicationClasspathSpis(); } + private static final IIORegistry registry; + static { + registry = new IIORegistry(); + } + /** * Returns the default {@code IIORegistry} instance used by * the Image I/O API. This instance should be used for all * registry functions. - * - *

Each {@code ThreadGroup} will receive its own instance. - * - * @return the default registry for the current - * {@code ThreadGroup}. + * @return the default registry for the Image I/O API */ public static IIORegistry getDefaultInstance() { - AppContext context = AppContext.getAppContext(); - IIORegistry registry = - (IIORegistry)context.get(IIORegistry.class); - if (registry == null) { - // Create an instance for this AppContext - registry = new IIORegistry(); - context.put(IIORegistry.class, registry); - } return registry; } diff --git a/src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java b/src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java index 4436f89b2c72a..be9f40e13dfdf 100644 --- a/src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java +++ b/src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java @@ -78,7 +78,7 @@ * proxy for the heavyweight service. * *

An application may customize the contents of a registry as it - * sees fit, so long as it has the appropriate runtime permission. + * sees fit. * *

For information on how to create and deploy service providers, * refer to the documentation on {@link java.util.ServiceLoader ServiceLoader} @@ -658,6 +658,12 @@ public void deregisterAll(Class category) { /** * Deregisters all currently registered service providers from all * categories. + *

+ * If an application creates a new {@code ServiceRegistry} instance and registers providers, + * and at some point no longer needs the instance, it should call this method to ensure + * that all providers which are instances of {@link RegisterableService} + * receive a {@link RegisterableService#onDeregistration(ServiceRegistry, Class)} call back, + * before allowing the instance to be garbage collected. */ public void deregisterAll() { for (SubRegistry reg : categoryMap.values()) { diff --git a/test/jdk/javax/imageio/AppContextTest.java b/test/jdk/javax/imageio/AppContextTest.java deleted file mode 100644 index 1132f652d0372..0000000000000 --- a/test/jdk/javax/imageio/AppContextTest.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2001, 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. - * - * 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. - */ - -/* - * @test - * @bug 4421190 - * @summary Tests that Image I/O statics may be referenced properly from - * multiple AppContexts, as would be the case for multiple Applets in a - * single VM. Each AppContext should get its own copy of the registry - * and the caching parameters in the ImageIO class. - * @modules java.desktop/sun.awt - */ - -import java.io.File; -import java.io.IOException; - -import javax.imageio.ImageIO; -import javax.imageio.spi.IIORegistry; - -import sun.awt.SunToolkit; - -class TestThread extends Thread { - - IIORegistry registry; - boolean useCache; - File cacheDirectory; - boolean cacheSettingsOK = false; - String threadName; - - boolean gotCrosstalk = false; - - public TestThread(ThreadGroup tg, - boolean useCache, File cacheDirectory, - String threadName) { - super(tg, threadName); - this.useCache = useCache; - this.cacheDirectory = cacheDirectory; - this.threadName = threadName; - } - - public void run() { -// System.out.println("Thread " + threadName + " in thread group " + -// getThreadGroup().getName()); - - // Create a new AppContext as though we were an applet - SunToolkit.createNewAppContext(); - - // Get default registry and store reference - this.registry = IIORegistry.getDefaultInstance(); - - for (int i = 0; i < 10; i++) { -// System.out.println(threadName + -// ": setting cache parameters to " + -// useCache + ", " + cacheDirectory); - ImageIO.setUseCache(useCache); - ImageIO.setCacheDirectory(cacheDirectory); - - try { - sleep(1000L); - } catch (InterruptedException e) { - } - -// System.out.println(threadName + ": reading cache parameters"); - boolean newUseCache = ImageIO.getUseCache(); - File newCacheDirectory = ImageIO.getCacheDirectory(); - if (newUseCache != useCache || - newCacheDirectory != cacheDirectory) { -// System.out.println(threadName + ": got " + -// newUseCache + ", " + -// newCacheDirectory); -// System.out.println(threadName + ": crosstalk encountered!"); - gotCrosstalk = true; - } - } - } - - public IIORegistry getRegistry() { - return registry; - } - - public boolean gotCrosstalk() { - return gotCrosstalk; - } -} - -public class AppContextTest { - - public AppContextTest() { - ThreadGroup tg0 = new ThreadGroup("ThreadGroup0"); - ThreadGroup tg1 = new ThreadGroup("ThreadGroup1"); - - TestThread t0 = - new TestThread(tg0, false, null, "TestThread 0"); - TestThread t1 = - new TestThread(tg1, true, new File("."), "TestThread 1"); - - t0.start(); - t1.start(); - - try { - t0.join(); - } catch (InterruptedException ie0) { - } - try { - t1.join(); - } catch (InterruptedException ie1) { - } - - if (t0.gotCrosstalk() || t1.gotCrosstalk()) { - throw new RuntimeException("ImageIO methods had crosstalk!"); - } - - if (t0.getRegistry() == t1.getRegistry()) { - throw new RuntimeException("ThreadGroups had same IIORegistry!"); - } - } - - public static void main(String[] args) throws IOException { - new AppContextTest(); - } -} From 308e472c4b71800c0399b39734f1c7f2982db84d Mon Sep 17 00:00:00 2001 From: prrace Date: Wed, 20 Aug 2025 13:33:01 -0700 Subject: [PATCH 3/3] 8365292 --- .../share/classes/javax/imageio/spi/IIORegistry.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/java.desktop/share/classes/javax/imageio/spi/IIORegistry.java b/src/java.desktop/share/classes/javax/imageio/spi/IIORegistry.java index 077dbed070cb2..4f8ae8f2d1e9a 100644 --- a/src/java.desktop/share/classes/javax/imageio/spi/IIORegistry.java +++ b/src/java.desktop/share/classes/javax/imageio/spi/IIORegistry.java @@ -104,10 +104,7 @@ private IIORegistry() { registerApplicationClasspathSpis(); } - private static final IIORegistry registry; - static { - registry = new IIORegistry(); - } + private static final IIORegistry registry = new IIORegistry(); /** * Returns the default {@code IIORegistry} instance used by