8039081: [TEST_BUG] Test java/awt/TrayIcon/PopupMenuLeakTest/PopupMenuLeakTest.java fails
Reviewed-by: serb, psadhukhan
--- a/jdk/src/java.desktop/share/classes/java/awt/TrayIcon.java Wed Aug 03 15:18:58 2016 +0800
+++ b/jdk/src/java.desktop/share/classes/java/awt/TrayIcon.java Fri Aug 05 15:48:37 2016 +0530
@@ -703,6 +703,9 @@
synchronized (this) {
p = peer;
peer = null;
+ if (popup != null) {
+ popup.removeNotify();
+ }
}
if (p != null) {
p.dispose();
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java Wed Aug 03 15:18:58 2016 +0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java Fri Aug 05 15:48:37 2016 +0530
@@ -93,7 +93,6 @@
if (XWM.getWMID() != XWM.METACITY_WM) {
parentXED = dummyXED; // We don't like to leave it 'null'.
-
} else {
parentXED = new XEventDispatcher() {
// It's executed under AWTLock.
@@ -300,10 +299,19 @@
removeXED(getWindow(), eframeXED);
removeXED(eframeParentID, parentXED);
+ removeListeners();
eframe.realDispose();
balloon.dispose();
+ tooltip.dispose();
isTrayIconDisplayed = false;
+ canvas.dispose();
+ canvas = null;
+ popup = null;
+ balloon = null;
+ tooltip = null;
XToolkit.targetDisposedPeer(target, this);
+ target = null;
+ eframe = null;
}
public static void suppressWarningString(Window w) {
@@ -416,6 +424,12 @@
eframe.addMouseListener(eventProxy);
}
+ void removeListeners() {
+ canvas.removeMouseListener(eventProxy);
+ canvas.removeMouseMotionListener(eventProxy);
+ eframe.removeMouseListener(eventProxy);
+ }
+
long getWindow() {
return AWTAccessor.getComponentAccessor()
.<XEmbeddedFramePeer>getPeer(eframe).getWindow();
@@ -550,6 +564,11 @@
super.repaintImage(doClear || (old_autosize != autosize));
}
+
+ public void dispose() {
+ super.dispose();
+ target = null;
+ }
}
@SuppressWarnings("serial") // JDK-implementation class
@@ -573,6 +592,10 @@
repaintImage(true);
}
+ public void dispose() {
+ observer = null;
+ }
+
// Invoke on EDT.
protected void repaintImage(boolean doClear) {
Graphics g = getGraphics();
--- a/jdk/test/java/awt/TrayIcon/PopupMenuLeakTest/PopupMenuLeakTest.java Wed Aug 03 15:18:58 2016 +0800
+++ b/jdk/test/java/awt/TrayIcon/PopupMenuLeakTest/PopupMenuLeakTest.java Fri Aug 05 15:48:37 2016 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, 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
@@ -22,17 +22,25 @@
*/
/*
- @test
- @key headful
- @bug 8007220
- @summary Reference to the popup leaks after the TrayIcon is removed
- @author Petr Pchelko
+ @test
+ @key headful
+ @bug 8007220 8039081
+ @summary Reference to the popup leaks after the TrayIcon is removed.
+ @requires os.family != "windows"
@library ../../../../lib/testlibrary/
@build ExtendedRobot
@run main/othervm -Xmx50m PopupMenuLeakTest
*/
-import java.awt.*;
+import java.awt.AWTException;
+import java.awt.Color;
+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 javax.swing.SwingUtilities;
import java.awt.image.BufferedImage;
@@ -45,7 +53,6 @@
static final AtomicReference<WeakReference<TrayIcon>> iconWeakReference = new AtomicReference<>();
static final AtomicReference<WeakReference<PopupMenu>> popupWeakReference = new AtomicReference<>();
static ExtendedRobot robot;
-
public static void main(String[] args) throws Exception {
robot = new ExtendedRobot();
SwingUtilities.invokeAndWait(PopupMenuLeakTest::createSystemTrayIcon);
@@ -55,8 +62,8 @@
sleep();
SwingUtilities.invokeAndWait(PopupMenuLeakTest::removeIcon);
sleep();
+ 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() {
@@ -78,12 +85,17 @@
private static void assertCollected(WeakReference<?> reference, String message) {
java.util.List<byte[]> bytes = new ArrayList<>();
for (int i = 0; i < 5; i ++) {
+ if (reference.get() == null) {
+ // reference is collected, avoid OOMs.
+ break;
+ }
try {
while (true) {
- bytes.add(new byte[1024]);
+ bytes.add(new byte[4096]);
}
} catch (OutOfMemoryError err) {
- bytes = new ArrayList<>();
+ bytes.clear();
+ causeGC();
}
}
if (reference.get() != null) {
@@ -91,6 +103,13 @@
}
}
+ private static void causeGC() {
+ System.gc();
+ System.runFinalization();
+ robot.delay(1000);
+ }
+
+
private static void createSystemTrayIcon() {
final TrayIcon trayIcon = new TrayIcon(createTrayIconImage());
trayIcon.setImageAutoSize(true);