JDK-6475361 : Attempting to remove help menu from java.awt.MenuBar throws NullPointerException
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: solaris_10
  • CPU: sparc
  • Submitted: 2006-09-26
  • Updated: 2017-12-21
  • Resolved: 2015-01-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8 JDK 9 Other
7u131Fixed 8u60Fixed 9 b52Fixed openjdk7uFixed
Description
FULL PRODUCT VERSION :
java version "1.6.0-rc"
Java(TM) SE Runtime Environment (build 1.6.0-rc-b99)
Java HotSpot(TM) Client VM (build 1.6.0-rc-b99, mixed mode, sharing)
 
But this bug occurs in every version of the JDK from version 1.0.2 onward

ADDITIONAL OS VERSION INFORMATION :
OS independent; occurs in all OS's

A DESCRIPTION OF THE PROBLEM :
Calling java.awt.MenuBar.setHelpMenu(null) is intended to remove the help menu. There is no other way to remove the help menu, and the design of the code clearly shows that this is the intended way to remove the help menu.

However, due to a coding error, it generates a null pointer exception instead. This error was found by FindBugs, and is in fact the only null pointer warning generated by FindBugs on JDK 1.0.2 that still exists in jdk1.6.0-b99.

Here is the relevant code:

 public void setHelpMenu(Menu m) {
        synchronized (getTreeLock()) {
            if (helpMenu == m) {
                return;
            }
            if (helpMenu != null) {
                remove(helpMenu);
            }
            if (m.parent != this) {
                add(m);
            }
            helpMenu = m;
            if (m != null) {
                m.isHelpMenu = true;
                m.parent = this;
                MenuBarPeer peer = (MenuBarPeer)this.peer;
                if (peer != null) {
                    if (m.peer == null) {
                        m.addNotify();
                    }
                    peer.addHelpMenu(m);
                }
            }
        }
    }


The check to see if (m != null) indicates that the developer considered a null
value for m to be a legal value. However, m is dereferenced before then, at
if (m.parent != this), and thus a null pointer exception is generated.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create a java.awt.MenuBar, set a non-null help menu (using setHelpMenu(...)) and then
set a null help menu (using setHelpMenu(...)).

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The help menu is removed.
ACTUAL -
a null pointer exception occurs

ERROR MESSAGES/STACK TRACES THAT OCCUR :
xception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at java.awt.MenuBar.setHelpMenu(MenuBar.java:164)
	at RemoveHelpMenu$1.actionPerformed(RemoveHelpMenu.java:22)
	at java.awt.MenuItem.processActionEvent(MenuItem.java:597)
	at java.awt.MenuItem.processEvent(MenuItem.java:556)
	at java.awt.MenuComponent.dispatchEventImpl(MenuComponent.java:298)
	at java.awt.MenuComponent.dispatchEvent(MenuComponent.java:286)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:466)
	at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:269)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:184)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:176)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;


public class RemoveHelpMenu {
	 MenuBar menuBar;
	    public MenuBar createMenuBar() {
	  
	        //Create the menu bar.
	        menuBar = new MenuBar();
	        
	        Menu helpMenu = new Menu("Help Menu");
	        MenuItem getHelp = new MenuItem("Remove help menu");
	        getHelp.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent arg0) {
					menuBar.setHelpMenu(null);
					
				}});
			helpMenu.add(getHelp);
	        
	        menuBar.setHelpMenu(helpMenu);
	        return menuBar;
	    }

	   
	    /**
	     * Create the GUI and show it.  For thread safety,
	     * this method should be invoked from the
	     * event-dispatching thread.
	     */
	    private static void createAndShowGUI() {
	        //Create and set up the window.
	        JFrame frame = new JFrame("RemoveHelpMenu Test");
	        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	        //Create and set up the content pane.
	        RemoveHelpMenu demo = new RemoveHelpMenu();
	        frame.setMenuBar(demo.createMenuBar());


	        //Display the window.
	        frame.setSize(450, 260);
	        frame.setVisible(true);
	    }

	    public static void main(String[] args) {
	        javax.swing.SwingUtilities.invokeLater(new Runnable() {
	            public void run() {
	                createAndShowGUI();
	            }
	        });
	    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Don't use help menus, or don't remove them.

Comments
EVALUATION Another issue is related to this bug. If help menu is removed with menuBar.remove(helpMenu) call, then menuBar.getHelpMenu() still returns the removed menu. I think this should be corrected to return null value.
08-11-2006

EVALUATION I consider this CR as not a bug: for example the call to menuBar.add(null) also throws NPE. Moreover, the submitter is not right that help menu can be removed only with the call menuBar.setHelpMenu(null) - I have found that menuBar.remove(helpMenu) can be used for this action. However, I'm not closing this CR as these NPEs should be reflected in the JavaDoc for MenuBar methods.
28-09-2006