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.
*
* 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
* questions.
*/
package java.awt;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
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 javax.accessibility.*;
import sun.awt.AWTAccessor;
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;
/**
* This class represents a check box that can be included in a menu.
@ -43,7 +50,8 @@ import sun.awt.AWTAccessor;
* of {@code CheckBoxMenuItem}:
* <p>
* <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;">
* <p>
* 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 #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 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.
*
* 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
* questions.
*/
package java.awt;
import java.awt.event.KeyEvent;
import java.awt.peer.MenuPeer;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Vector;
import java.util.Enumeration;
import java.awt.peer.MenuPeer;
import java.awt.event.KeyEvent;
import javax.accessibility.*;
import java.util.Vector;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import sun.awt.AWTAccessor;
/**
@ -78,7 +83,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible {
* @serial
* @see #countItems()
*/
Vector<MenuItem> items = new Vector<>();
private final Vector<MenuItem> items = new Vector<>();
/**
* This field indicates whether the menu has the
@ -92,7 +97,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible {
* @serial
* @see #isTearOff()
*/
boolean tearOff;
private final boolean tearOff;
/**
* This field will be set to {@code true}
@ -102,7 +107,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible {
*
* @serial
*/
boolean isHelpMenu;
volatile boolean isHelpMenu;
private static final String base = "menu";
private static int nameCounter = 0;
@ -415,8 +420,8 @@ public class Menu extends MenuItem implements MenuContainer, Accessible {
if (peer != null) {
peer.delItem(index);
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.
*
* 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
* questions.
*/
package java.awt;
import java.awt.event.KeyEvent;
import java.awt.peer.MenuBarPeer;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Vector;
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 java.awt.peer.MenuBarPeer;
import java.awt.event.KeyEvent;
import javax.accessibility.*;
/**
* The {@code MenuBar} class encapsulates the platform's
@ -94,7 +99,7 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible
* @serial
* @see #countMenus()
*/
Vector<Menu> menus = new Vector<>();
private final Vector<Menu> menus = new Vector<>();
/**
* This menu is a special menu dedicated to
@ -106,7 +111,7 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible
* @see #getHelpMenu()
* @see #setHelpMenu(Menu)
*/
Menu helpMenu;
private volatile Menu helpMenu;
private static final String base = "menubar";
private static int nameCounter = 0;
@ -252,8 +257,8 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible
if (peer != null) {
peer.delMenu(index);
m.removeNotify();
m.parent = null;
}
m.parent = null;
if (helpMenu == m) {
helpMenu = null;
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.
*
* 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
* questions.
*/
package java.awt;
import java.awt.peer.MenuComponentPeer;
import java.awt.event.ActionEvent;
import java.awt.peer.MenuComponentPeer;
import java.io.IOException;
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.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
* 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 MenuContainer parent;
transient volatile MenuContainer parent;
/**
* The {@code AppContext} of the {@code MenuComponent}.
* 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
@ -77,7 +84,7 @@ public abstract class MenuComponent implements java.io.Serializable {
* @see #setFont(Font)
* @see #getFont()
*/
volatile Font font;
private volatile Font font;
/**
* 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 #setName(String)
*/
private String name;
private volatile String name;
/**
* A variable to indicate whether a name is explicitly set.
@ -94,14 +101,14 @@ public abstract class MenuComponent implements java.io.Serializable {
* @serial
* @see #setName(String)
*/
private boolean nameExplicitlySet = false;
private volatile boolean nameExplicitlySet;
/**
* Defaults to {@code false}.
* @serial
* @see #dispatchEvent(AWTEvent)
*/
boolean newEventsOnly = false;
volatile boolean newEventsOnly;
/*
* 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.
*
* 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
* questions.
*/
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.event.*;
import java.util.EventListener;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
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;
/**
@ -111,7 +121,7 @@ public class MenuItem extends MenuComponent implements Accessible {
* @see #isEnabled()
* @see #setEnabled(boolean)
*/
boolean enabled = true;
private volatile boolean enabled = true;
/**
* {@code label} is the label of a menu item.
@ -121,7 +131,7 @@ public class MenuItem extends MenuComponent implements Accessible {
* @see #getLabel()
* @see #setLabel(String)
*/
String label;
volatile String label;
/**
* This field indicates the command that has been issued
@ -134,7 +144,7 @@ public class MenuItem extends MenuComponent implements Accessible {
* @see #setActionCommand(String)
* @see #getActionCommand()
*/
String actionCommand;
private volatile String actionCommand;
/**
* The eventMask is ONLY set by subclasses via enableEvents.
@ -144,9 +154,9 @@ public class MenuItem extends MenuComponent implements Accessible {
*
* @serial
*/
long eventMask;
volatile long eventMask;
transient ActionListener actionListener;
private transient volatile ActionListener actionListener;
/**
* A sequence of key stokes that ia associated with
@ -160,7 +170,7 @@ public class MenuItem extends MenuComponent implements Accessible {
* @see #setShortcut(MenuShortcut)
* @see #deleteShortcut()
*/
private MenuShortcut shortcut = null;
private volatile MenuShortcut shortcut;
private static final String base = "menuitem";
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.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,8 +26,9 @@
package java.awt;
import java.awt.peer.PopupMenuPeer;
import javax.accessibility.*;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import sun.awt.AWTAccessor;
@ -48,7 +49,7 @@ public class PopupMenu extends Menu {
private static final String base = "popup";
static int nameCounter = 0;
transient boolean isTrayIconPopup = false;
transient volatile boolean isTrayIconPopup;
static {
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");
}
}
}