--- old/test/java/awt/TrayIcon/PopupMenuLeakTest/PopupMenuLeakTest.java 2015-11-30 20:41:53.391443000 +0530 +++ new/test/java/awt/TrayIcon/PopupMenuLeakTest/PopupMenuLeakTest.java 2015-11-30 20:41:53.011253000 +0530 @@ -22,40 +22,46 @@ */ /* - @test - @bug 8007220 - @summary Reference to the popup leaks after the TrayIcon is removed - @author Petr Pchelko - @library ../../../../lib/testlibrary/ - @build ExtendedRobot + @test + @bug 8007220 8039081 + @summary Reference to the popup should not leak after the TrayIcon is + removed from system tray. @run main/othervm -Xmx50m PopupMenuLeakTest */ -import java.awt.*; -import javax.swing.SwingUtilities; - +import java.awt.Color; +import java.awt.Frame; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.MenuItem; +import java.awt.PopupMenu; +import java.awt.RenderingHints; +import java.awt.SystemTray; +import java.awt.TrayIcon; import java.awt.image.BufferedImage; +import javax.swing.SwingUtilities; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.concurrent.atomic.AtomicReference; public class PopupMenuLeakTest { - static final AtomicReference> iconWeakReference = new AtomicReference<>(); - static final AtomicReference> popupWeakReference = new AtomicReference<>(); - static ExtendedRobot robot; + static final AtomicReference> iconWeakReference + = new AtomicReference<>(); + static final AtomicReference> popupWeakReference + = new AtomicReference<>(); + static Frame popupMenuParentFrame; public static void main(String[] args) throws Exception { - robot = new ExtendedRobot(); SwingUtilities.invokeAndWait(PopupMenuLeakTest::createSystemTrayIcon); - sleep(); - // To make the test automatic we explicitly call addNotify on a popup to create the peer + // To automate the test, explicitly call addNotify on a popup + // to create the peer. SwingUtilities.invokeAndWait(PopupMenuLeakTest::addNotifyPopup); - sleep(); SwingUtilities.invokeAndWait(PopupMenuLeakTest::removeIcon); - sleep(); - assertCollected(popupWeakReference.get(), "Failed, reference to popup not collected"); - assertCollected(iconWeakReference.get(), "Failed, reference to tray icon not collected"); + assertCollected(popupWeakReference.get(), + "Failed, reference to popup not collected"); + assertCollected(iconWeakReference.get(), + "Failed, reference to tray icon not collected"); } private static void addNotifyPopup() { @@ -72,18 +78,20 @@ throw new RuntimeException("Failed: TrayIcon collected too early"); } SystemTray.getSystemTray().remove(icon); + + PopupMenu menu = popupWeakReference.get().get(); + popupMenuParentFrame.remove(menu); + popupMenuParentFrame.dispose(); } - private static void assertCollected(WeakReference reference, String message) { + private static void assertCollected(WeakReference reference, + String message) { java.util.List bytes = new ArrayList<>(); - for (int i = 0; i < 5; i ++) { - try { - while (true) { - bytes.add(new byte[1024]); - } - } catch (OutOfMemoryError err) { - bytes = new ArrayList<>(); + try { + while (true) { + bytes.add(new byte[4096]); } + } catch (OutOfMemoryError err) { } if (reference.get() != null) { throw new RuntimeException(message); @@ -95,28 +103,31 @@ trayIcon.setImageAutoSize(true); try { - // Add tray icon to system tray *before* adding popup menu to demonstrate buggy behaviour + // Add tray icon to system tray *before* adding popup menu. trayIcon.setPopupMenu(createTrayIconPopupMenu()); SystemTray.getSystemTray().add(trayIcon); iconWeakReference.set(new WeakReference<>(trayIcon)); - popupWeakReference.set(new WeakReference<>(trayIcon.getPopupMenu())); - } catch (final AWTException awte) { - awte.printStackTrace(); + popupWeakReference.set(new WeakReference<>( + trayIcon.getPopupMenu())); + } catch (final Exception ex) { + ex.printStackTrace(); } } private static Image createTrayIconImage() { - /** - * Create a small image of a red circle to use as the icon for the tray icon - */ + // Create a small red circle image to use as the icon for tray icon. int trayIconImageSize = 32; - final BufferedImage trayImage = new BufferedImage(trayIconImageSize, trayIconImageSize, BufferedImage.TYPE_INT_ARGB); - final Graphics2D trayImageGraphics = (Graphics2D) trayImage.getGraphics(); + final BufferedImage trayImage = new BufferedImage(trayIconImageSize, + trayIconImageSize, BufferedImage.TYPE_INT_ARGB); + final Graphics2D trayImageGraphics + = (Graphics2D) trayImage.getGraphics(); - trayImageGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + trayImageGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); trayImageGraphics.setColor(new Color(255, 255, 255, 0)); - trayImageGraphics.fillRect(0, 0, trayImage.getWidth(), trayImage.getHeight()); + trayImageGraphics.fillRect(0, 0, trayImage.getWidth(), + trayImage.getHeight()); trayImageGraphics.setColor(Color.red); @@ -137,13 +148,14 @@ } private static PopupMenu createTrayIconPopupMenu() { + popupMenuParentFrame = new Frame(); + popupMenuParentFrame.setVisible(true); + final PopupMenu trayIconPopupMenu = new PopupMenu(); final MenuItem popupMenuItem = new MenuItem("TEST!"); trayIconPopupMenu.add(popupMenuItem); - return trayIconPopupMenu; - } - private static void sleep() { - robot.waitForIdle(100); + popupMenuParentFrame.add(trayIconPopupMenu); + return trayIconPopupMenu; } -} +} \ No newline at end of file