From 982aa3f8ead84817be5373c3257d48feab1758d3 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Thu, 8 Jan 2026 19:47:01 +0000 Subject: [PATCH] 8336654: [lworld] Tests depending on sun.awt.AppContext can fail when run with migrated classes Reviewed-by: serb, azvegint --- .../classes/com/apple/laf/AquaUtils.java | 41 +++++-- .../share/classes/sun/awt/AppContext.java | 19 --- .../classes/sun/awt/image/ImageCache.java | 8 +- .../swing/Security/6657138/bug6657138.java | 108 ------------------ 4 files changed, 33 insertions(+), 143 deletions(-) delete mode 100644 test/jdk/javax/swing/Security/6657138/bug6657138.java diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaUtils.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaUtils.java index da1785a9a63..5e68cc7a82c 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaUtils.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaUtils.java @@ -35,8 +35,6 @@ import javax.swing.*; import javax.swing.border.Border; import javax.swing.plaf.UIResource; -import sun.awt.AppContext; - import sun.lwawt.macosx.CPlatformWindow; import sun.swing.SwingUtilities2; @@ -150,13 +148,34 @@ final class AquaUtils { protected abstract T create(); } - abstract static class RecyclableSingleton { - final T get() { - return AppContext.getSoftReferenceValue(this, () -> getInstance()); - } + abstract static class LazySingleton { + T instance; - void reset() { - AppContext.getAppContext().remove(this); + final T get() { + if (instance == null) { + instance = getInstance(); + } + return instance; + } + + abstract T getInstance(); + } + + abstract static class RecyclableSingleton { + + SoftReference ref; + + final T get() { + T instance; + if (ref != null) { + instance = ref.get(); + if (instance != null) { + return instance; + } + } + instance = getInstance(); + ref = new SoftReference<>(instance); + return instance; } abstract T getInstance(); @@ -197,11 +216,11 @@ final class AquaUtils { protected abstract V getInstance(K key); } - private static final RecyclableSingleton enableAnimations = new RecyclableSingleton() { + private static final LazySingleton enableAnimations = new LazySingleton() { @Override protected Boolean getInstance() { - final String sizeProperty = System.getProperty(ANIMATIONS_PROPERTY); - return !"false".equals(sizeProperty); // should be true by default + final String animationsProperty = System.getProperty(ANIMATIONS_PROPERTY); + return !"false".equals(animationsProperty); // should be true by default } }; private static boolean animationsEnabled() { diff --git a/src/java.desktop/share/classes/sun/awt/AppContext.java b/src/java.desktop/share/classes/sun/awt/AppContext.java index 39df737badb..01b1dd09887 100644 --- a/src/java.desktop/share/classes/sun/awt/AppContext.java +++ b/src/java.desktop/share/classes/sun/awt/AppContext.java @@ -47,7 +47,6 @@ import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Supplier; /** * The AppContext is a table referenced by ThreadGroup which stores @@ -735,24 +734,6 @@ public final class AppContext { } return changeSupport.getPropertyChangeListeners(propertyName); } - - public static T getSoftReferenceValue(Object key, - Supplier supplier) { - - final AppContext appContext = AppContext.getAppContext(); - @SuppressWarnings("unchecked") - SoftReference ref = (SoftReference) appContext.get(key); - if (ref != null) { - final T object = ref.get(); - if (object != null) { - return object; - } - } - final T object = supplier.get(); - ref = new SoftReference<>(object); - appContext.put(key, ref); - return object; - } } final class MostRecentKeyValue { diff --git a/src/java.desktop/share/classes/sun/awt/image/ImageCache.java b/src/java.desktop/share/classes/sun/awt/image/ImageCache.java index eed1aa5bdb7..b7ac69923da 100644 --- a/src/java.desktop/share/classes/sun/awt/image/ImageCache.java +++ b/src/java.desktop/share/classes/sun/awt/image/ImageCache.java @@ -29,7 +29,6 @@ import java.awt.*; import java.lang.ref.*; import java.util.*; import java.util.concurrent.locks.*; -import sun.awt.AppContext; /** * ImageCache - A fixed pixel count sized cache of Images keyed by arbitrary @@ -37,8 +36,6 @@ import sun.awt.AppContext; * dropped by the GC if heap memory gets tight. When our size hits max pixel * count least recently requested images are removed first. * - * The ImageCache must be used from the thread with an AppContext only. - * */ public final class ImageCache { @@ -56,9 +53,10 @@ public final class ImageCache { // Reference queue for tracking lost softreferences to images in the cache private final ReferenceQueue referenceQueue = new ReferenceQueue<>(); + private static final ImageCache instance = new ImageCache(); + public static ImageCache getInstance() { - return AppContext.getSoftReferenceValue(ImageCache.class, - () -> new ImageCache()); + return instance; } ImageCache(final int maxPixelCount) { diff --git a/test/jdk/javax/swing/Security/6657138/bug6657138.java b/test/jdk/javax/swing/Security/6657138/bug6657138.java deleted file mode 100644 index 4670d57595c..00000000000 --- a/test/jdk/javax/swing/Security/6657138/bug6657138.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2009, 2018, 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 6657138 - * @summary Verifies that buttons and labels don't share their ui's across appContexts - * @author Alexander Potochkin - * @modules java.desktop/sun.awt - */ - -import sun.awt.SunToolkit; - -import javax.swing.*; -import javax.swing.plaf.ButtonUI; -import javax.swing.plaf.ComponentUI; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -public class bug6657138 implements Runnable { - - private static Map> componentMap = - Collections.synchronizedMap( - new HashMap>()); - - public void run() { - SunToolkit.createNewAppContext(); - try { - testUIMap(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - private static void testUIMap() throws Exception { - UIManager.LookAndFeelInfo[] lafs = UIManager.getInstalledLookAndFeels(); - Set components = componentMap.keySet(); - for (JComponent c : components) { - Map uiMap = componentMap.get(c); - - for (UIManager.LookAndFeelInfo laf : lafs) { - if ("Nimbus".equals(laf.getName())) { - // for some unclear reasons - // Nimbus ui delegate for a button is null - // when this method is called from the new AppContext - continue; - } - String className = laf.getClassName(); - try { - UIManager.setLookAndFeel(className); - } catch (final UnsupportedLookAndFeelException ignored) { - continue; - } - ComponentUI ui = UIManager.getUI(c); - if (ui == null) { - throw new RuntimeException("UI is null for " + c); - } - if (ui == uiMap.get(laf.getName())) { - throw new RuntimeException( - "Two AppContexts share the same UI delegate! \n" + - c + "\n" + ui); - } - uiMap.put(laf.getName(), ui); - } - } - } - - public static void main(String[] args) throws Exception { - componentMap.put(new JButton("JButton"), - new HashMap()); - componentMap.put(new JToggleButton("JToggleButton"), - new HashMap()); - componentMap.put(new JRadioButton("JRadioButton"), - new HashMap()); - componentMap.put(new JCheckBox("JCheckBox"), - new HashMap()); - componentMap.put(new JCheckBox("JLabel"), - new HashMap()); - testUIMap(); - ThreadGroup group = new ThreadGroup("6657138"); - Thread thread = new Thread(group, new bug6657138()); - thread.start(); - thread.join(); - } -} -