8165769: Hang in the help menu item

Reviewed-by: alexsch, aivanov
This commit is contained in:
Sergey Bylokhov 2016-12-08 08:11:47 -08:00
parent 7428af941d
commit e8208dd0be
7 changed files with 218 additions and 56 deletions

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,17 +22,24 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package java.awt; package java.awt;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.peer.CheckboxMenuItemPeer; import java.awt.peer.CheckboxMenuItemPeer;
import java.awt.event.*;
import java.util.EventListener;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException; import java.io.IOException;
import javax.accessibility.*; import java.io.ObjectInputStream;
import sun.awt.AWTAccessor; import java.io.ObjectOutputStream;
import java.util.EventListener;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleAction;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleValue;
import sun.awt.AWTAccessor;
/** /**
* This class represents a check box that can be included in a menu. * This class represents a check box that can be included in a menu.
@ -43,7 +50,8 @@ import sun.awt.AWTAccessor;
* of {@code CheckBoxMenuItem}: * of {@code CheckBoxMenuItem}:
* <p> * <p>
* <img src="doc-files/MenuBar-1.gif" * <img src="doc-files/MenuBar-1.gif"
* alt="Menu labeled Examples, containing items Basic, Simple, Check, and More Examples. The Check item is a CheckBoxMenuItem instance, in the off state." * alt="Menu labeled Examples, containing items Basic, Simple, Check, and More
* Examples. The Check item is a CheckBoxMenuItem instance, in the off state."
* style="float:center; margin: 7px 10px;"> * style="float:center; margin: 7px 10px;">
* <p> * <p>
* The item labeled {@code Check} shows a check box menu item * The item labeled {@code Check} shows a check box menu item
@ -84,9 +92,9 @@ public class CheckboxMenuItem extends MenuItem implements ItemSelectable, Access
* @see #getState() * @see #getState()
* @see #setState(boolean) * @see #setState(boolean)
*/ */
boolean state = false; private volatile boolean state;
transient ItemListener itemListener; private transient volatile ItemListener itemListener;
private static final String base = "chkmenuitem"; private static final String base = "chkmenuitem";
private static int nameCounter = 0; private static int nameCounter = 0;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,15 +22,20 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package java.awt; package java.awt;
import java.awt.event.KeyEvent;
import java.awt.peer.MenuPeer;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.util.Vector;
import java.util.Enumeration; import java.util.Enumeration;
import java.awt.peer.MenuPeer; import java.util.Vector;
import java.awt.event.KeyEvent;
import javax.accessibility.*; import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import sun.awt.AWTAccessor; import sun.awt.AWTAccessor;
/** /**
@ -78,7 +83,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible {
* @serial * @serial
* @see #countItems() * @see #countItems()
*/ */
Vector<MenuItem> items = new Vector<>(); private final Vector<MenuItem> items = new Vector<>();
/** /**
* This field indicates whether the menu has the * This field indicates whether the menu has the
@ -92,7 +97,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible {
* @serial * @serial
* @see #isTearOff() * @see #isTearOff()
*/ */
boolean tearOff; private final boolean tearOff;
/** /**
* This field will be set to {@code true} * This field will be set to {@code true}
@ -102,7 +107,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible {
* *
* @serial * @serial
*/ */
boolean isHelpMenu; volatile boolean isHelpMenu;
private static final String base = "menu"; private static final String base = "menu";
private static int nameCounter = 0; private static int nameCounter = 0;
@ -415,8 +420,8 @@ public class Menu extends MenuItem implements MenuContainer, Accessible {
if (peer != null) { if (peer != null) {
peer.delItem(index); peer.delItem(index);
mi.removeNotify(); mi.removeNotify();
mi.parent = null;
} }
mi.parent = null;
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,16 +22,21 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package java.awt; package java.awt;
import java.awt.event.KeyEvent;
import java.awt.peer.MenuBarPeer;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.util.Vector;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Vector;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import sun.awt.AWTAccessor; import sun.awt.AWTAccessor;
import java.awt.peer.MenuBarPeer;
import java.awt.event.KeyEvent;
import javax.accessibility.*;
/** /**
* The {@code MenuBar} class encapsulates the platform's * The {@code MenuBar} class encapsulates the platform's
@ -94,7 +99,7 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible
* @serial * @serial
* @see #countMenus() * @see #countMenus()
*/ */
Vector<Menu> menus = new Vector<>(); private final Vector<Menu> menus = new Vector<>();
/** /**
* This menu is a special menu dedicated to * This menu is a special menu dedicated to
@ -106,7 +111,7 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible
* @see #getHelpMenu() * @see #getHelpMenu()
* @see #setHelpMenu(Menu) * @see #setHelpMenu(Menu)
*/ */
Menu helpMenu; private volatile Menu helpMenu;
private static final String base = "menubar"; private static final String base = "menubar";
private static int nameCounter = 0; private static int nameCounter = 0;
@ -252,8 +257,8 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible
if (peer != null) { if (peer != null) {
peer.delMenu(index); peer.delMenu(index);
m.removeNotify(); m.removeNotify();
m.parent = null;
} }
m.parent = null;
if (helpMenu == m) { if (helpMenu == m) {
helpMenu = null; helpMenu = null;
m.isHelpMenu = false; m.isHelpMenu = false;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,21 +22,28 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package java.awt; package java.awt;
import java.awt.peer.MenuComponentPeer;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.peer.MenuComponentPeer;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import sun.awt.AppContext;
import sun.awt.AWTAccessor;
import sun.awt.ComponentFactory;
import javax.accessibility.*;
import java.security.AccessControlContext; import java.security.AccessControlContext;
import java.security.AccessController; import java.security.AccessController;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleComponent;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleSelection;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
import sun.awt.AWTAccessor;
import sun.awt.AppContext;
import sun.awt.ComponentFactory;
/** /**
* The abstract class {@code MenuComponent} is the superclass * The abstract class {@code MenuComponent} is the superclass
* of all menu-related components. In this respect, the class * of all menu-related components. In this respect, the class
@ -60,13 +67,13 @@ public abstract class MenuComponent implements java.io.Serializable {
} }
transient volatile MenuComponentPeer peer; transient volatile MenuComponentPeer peer;
transient MenuContainer parent; transient volatile MenuContainer parent;
/** /**
* The {@code AppContext} of the {@code MenuComponent}. * The {@code AppContext} of the {@code MenuComponent}.
* This is set in the constructor and never changes. * This is set in the constructor and never changes.
*/ */
transient AppContext appContext; private transient volatile AppContext appContext;
/** /**
* The menu component's font. This value can be * The menu component's font. This value can be
@ -77,7 +84,7 @@ public abstract class MenuComponent implements java.io.Serializable {
* @see #setFont(Font) * @see #setFont(Font)
* @see #getFont() * @see #getFont()
*/ */
volatile Font font; private volatile Font font;
/** /**
* The menu component's name, which defaults to {@code null}. * The menu component's name, which defaults to {@code null}.
@ -85,7 +92,7 @@ public abstract class MenuComponent implements java.io.Serializable {
* @see #getName() * @see #getName()
* @see #setName(String) * @see #setName(String)
*/ */
private String name; private volatile String name;
/** /**
* A variable to indicate whether a name is explicitly set. * A variable to indicate whether a name is explicitly set.
@ -94,14 +101,14 @@ public abstract class MenuComponent implements java.io.Serializable {
* @serial * @serial
* @see #setName(String) * @see #setName(String)
*/ */
private boolean nameExplicitlySet = false; private volatile boolean nameExplicitlySet;
/** /**
* Defaults to {@code false}. * Defaults to {@code false}.
* @serial * @serial
* @see #dispatchEvent(AWTEvent) * @see #dispatchEvent(AWTEvent)
*/ */
boolean newEventsOnly = false; volatile boolean newEventsOnly;
/* /*
* The menu's AccessControlContext. * The menu's AccessControlContext.

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,15 +22,25 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package java.awt; package java.awt;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.peer.MenuItemPeer; import java.awt.peer.MenuItemPeer;
import java.awt.event.*;
import java.util.EventListener;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException; import java.io.IOException;
import javax.accessibility.*; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.EventListener;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleAction;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleValue;
import sun.awt.AWTAccessor; import sun.awt.AWTAccessor;
/** /**
@ -111,7 +121,7 @@ public class MenuItem extends MenuComponent implements Accessible {
* @see #isEnabled() * @see #isEnabled()
* @see #setEnabled(boolean) * @see #setEnabled(boolean)
*/ */
boolean enabled = true; private volatile boolean enabled = true;
/** /**
* {@code label} is the label of a menu item. * {@code label} is the label of a menu item.
@ -121,7 +131,7 @@ public class MenuItem extends MenuComponent implements Accessible {
* @see #getLabel() * @see #getLabel()
* @see #setLabel(String) * @see #setLabel(String)
*/ */
String label; volatile String label;
/** /**
* This field indicates the command that has been issued * This field indicates the command that has been issued
@ -134,7 +144,7 @@ public class MenuItem extends MenuComponent implements Accessible {
* @see #setActionCommand(String) * @see #setActionCommand(String)
* @see #getActionCommand() * @see #getActionCommand()
*/ */
String actionCommand; private volatile String actionCommand;
/** /**
* The eventMask is ONLY set by subclasses via enableEvents. * The eventMask is ONLY set by subclasses via enableEvents.
@ -144,9 +154,9 @@ public class MenuItem extends MenuComponent implements Accessible {
* *
* @serial * @serial
*/ */
long eventMask; volatile long eventMask;
transient ActionListener actionListener; private transient volatile ActionListener actionListener;
/** /**
* A sequence of key stokes that ia associated with * A sequence of key stokes that ia associated with
@ -160,7 +170,7 @@ public class MenuItem extends MenuComponent implements Accessible {
* @see #setShortcut(MenuShortcut) * @see #setShortcut(MenuShortcut)
* @see #deleteShortcut() * @see #deleteShortcut()
*/ */
private MenuShortcut shortcut = null; private volatile MenuShortcut shortcut;
private static final String base = "menuitem"; private static final String base = "menuitem";
private static int nameCounter = 0; private static int nameCounter = 0;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,8 +26,9 @@
package java.awt; package java.awt;
import java.awt.peer.PopupMenuPeer; import java.awt.peer.PopupMenuPeer;
import javax.accessibility.*;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import sun.awt.AWTAccessor; import sun.awt.AWTAccessor;
@ -48,7 +49,7 @@ public class PopupMenu extends Menu {
private static final String base = "popup"; private static final String base = "popup";
static int nameCounter = 0; static int nameCounter = 0;
transient boolean isTrayIconPopup = false; transient volatile boolean isTrayIconPopup;
static { static {
AWTAccessor.setPopupMenuAccessor( AWTAccessor.setPopupMenuAccessor(

View file

@ -0,0 +1,126 @@
/*
* Copyright (c) 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
* 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.
*/
import java.awt.Frame;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.PopupMenu;
import java.awt.Window;
/**
* @test
* @bug 8165769
* @key headful
*/
public final class WrongParentAfterRemoveMenu {
public static void main(final String[] args) {
testMenuBar();
testComponent();
testFrame();
}
private static void testFrame() {
// peer exists
Frame frame = new Frame();
try {
frame.pack();
PopupMenu popupMenu = new PopupMenu();
frame.add(popupMenu);
checkParent(popupMenu, frame);
frame.remove(popupMenu);
checkParent(popupMenu, null);
} finally {
frame.dispose();
}
// peer is null
frame = new Frame();
PopupMenu popupMenu = new PopupMenu();
frame.add(popupMenu);
checkParent(popupMenu, frame);
frame.remove(popupMenu);
checkParent(popupMenu, null);
}
private static void testComponent() {
// peer exists
Window w = new Window(null);
try {
w.pack();
PopupMenu popupMenu = new PopupMenu();
w.add(popupMenu);
checkParent(popupMenu, w);
w.remove(popupMenu);
checkParent(popupMenu, null);
} finally {
w.dispose();
}
// peer is null
w = new Window(null);
PopupMenu popupMenu = new PopupMenu();
w.add(popupMenu);
checkParent(popupMenu, w);
w.remove(popupMenu);
checkParent(popupMenu, null);
}
private static void testMenuBar() {
// peer exists
MenuBar mb = new MenuBar();
try {
mb.addNotify();
Menu m1 = new Menu();
Menu m2 = new Menu();
m1.add(m2);
mb.add(m1);
checkParent(m1, mb);
checkParent(m2, m1);
m1.remove(m2);
checkParent(m2, null);
mb.remove(m1);
checkParent(m1, null);
} finally {
mb.removeNotify();
}
// peer is null
mb = new MenuBar();
Menu m1 = new Menu();
Menu m2 = new Menu();
m1.add(m2);
mb.add(m1);
checkParent(m1, mb);
checkParent(m2, m1);
m1.remove(m2);
checkParent(m2, null);
mb.remove(m1);
checkParent(m1, null);
}
private static void checkParent(final Menu menu, final Object parent) {
if (menu.getParent() != parent) {
System.err.println("Expected: " + parent);
System.err.println("Actual: " + menu.getParent());
throw new RuntimeException("Wrong parent");
}
}
}