JDK-6598089 : JDK 7: AWT often goes into busy loop when showing dialog
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: OpenJDK6,7,7-pool
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux,linux_ubuntu,solaris_10
  • CPU: generic,x86,sparc
  • Submitted: 2007-08-28
  • Updated: 2011-01-19
  • Resolved: 2008-04-14
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 Other
7 b25Fixed OpenJDK6Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Description
I run NetBeans development builds on JDK 7 promotions. Normally this works well. In the last few JDK 7 promotions, however, I have noticed frequent hangs of the IDE that do not obviously involve NetBeans code. The last time this occurred (forcing me to switch to JDK 6u2), I was running a NB dev build (070815) on JDK 7 b18 and invoked the Find Usages dialog on projects/projectapi/src/org/netbeans/spi/project/DataFilesProviderImplementation.java in NetBeans sources. The dialog appeared, I selected some options, and clicked Find. But instead of closing the dialog and showing the results window, the dialog window stayed open, and the application froze with 100% CPU usage. The EQ thread was consumed doing something inside Dialog.show (called from NB code); the tails of a couple of representative thread dumps:

"AWT-EventQueue-1" prio=10 tid=0x084ee800 nid=0x113d runnable [0x86ee6000..0x86ee8030]
   java.lang.Thread.State: RUNNABLE
	at sun.awt.AppContext.get(AppContext.java:574)
	- locked <0x8bd25970> (a java.util.HashMap)
	at java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager(KeyboardFocusManager.java:190)
	- locked <0xa9a404a0> (a java.lang.Class for java.awt.KeyboardFocusManager)
	at java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager(KeyboardFocusManager.java:184)
	at java.awt.KeyboardFocusManager.getGlobalFocusedWindow(KeyboardFocusManager.java:753)
	- locked <0xa9a404a0> (a java.lang.Class for java.awt.KeyboardFocusManager)
	at java.awt.Window.isFocused(Window.java:2204)
	at sun.awt.X11.XComponentPeer.requestFocus(XComponentPeer.java:440)
	at java.awt.Component.requestFocusHelper(Component.java:7177)
	at java.awt.Component.requestFocus(Component.java:7017)
	at java.awt.DefaultKeyboardFocusManager.doRestoreFocus(DefaultKeyboardFocusManager.java:158)
	at java.awt.DefaultKeyboardFocusManager.restoreFocus(DefaultKeyboardFocusManager.java:116)
	at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:510)
	at java.awt.Component.dispatchEventImpl(Component.java:4292)
	at java.awt.Container.dispatchEventImpl(Container.java:2132)
	at java.awt.Component.dispatchEvent(Component.java:4250)
	at sun.awt.X11.XWindow$1.run(XWindow.java:378)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:227)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:610)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:276)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:201)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:195)
	at java.awt.Dialog$1.run(Dialog.java:1069)
	at java.awt.Dialog$3.run(Dialog.java:1123)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.awt.Dialog.show(Dialog.java:1121)

"AWT-EventQueue-1" prio=10 tid=0x084ee800 nid=0x113d runnable [0x86ee6000..0x86ee8030]
   java.lang.Thread.State: RUNNABLE
	at java.lang.reflect.Field.getFieldAccessor(Field.java:914)
	at java.lang.reflect.Field.setBoolean(Field.java:704)
	at sun.awt.X11.XWindow$1.run(XWindow.java:372)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:227)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:610)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:276)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:201)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:195)
	at java.awt.Dialog$1.run(Dialog.java:1069)
	at java.awt.Dialog$3.run(Dialog.java:1123)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.awt.Dialog.show(Dialog.java:1121)

The same problem occurred even after restarting the IDE. The freeze never corrects itself that I saw; the Java process must be killed from the command line. When I ran under JDK 6u2 instead, the same Find Usages call worked fine - the dialog closed quickly and results were shown as usual.

I have observed similar freezes on a number of occasions, always involving a dialog (I think about to close), running only AWT code.

I run on Ubuntu (7.04) with GNOME/Metacity.

Comments
SUGGESTED FIX ------- DefaultKeyboardFocusManager.java ------- *** /tmp/sccs.b_aG2K Wed Sep 19 17:35:37 2007 --- DefaultKeyboardFocusManager.java Wed Sep 19 17:34:39 2007 *************** *** 153,163 **** return doRestoreFocus(toFocus, null, clearOnFailure); } private boolean doRestoreFocus(Component toFocus, Component vetoedComponent, boolean clearOnFailure) { ! if (toFocus.isShowing() && toFocus.isFocusable() && toFocus.requestFocus(false, CausedFocusEvent.Cause.ROLLBACK)) { return true; } else { Component nextFocus = toFocus.preNextFocusHelper(); if (nextFocus != vetoedComponent --- 153,163 ---- return doRestoreFocus(toFocus, null, clearOnFailure); } private boolean doRestoreFocus(Component toFocus, Component vetoedComponent, boolean clearOnFailure) { ! if (toFocus != vetoedComponent && toFocus.isShowing() && toFocus.isFocusable() && toFocus.requestFocus(false, CausedFocusEvent.Cause.ROLLBACK)) { return true; } else { Component nextFocus = toFocus.preNextFocusHelper(); if (nextFocus != vetoedComponent
26-03-2008

EVALUATION It's worth to say that on Windows the problem is not reproducible. The reason is the following detail. When "another JRadioButton" (see above) is requested focus it gets focused on native level (in contrast to XAWT). And when DKFM tries to restore focus on the original JRadioButton (it requests focus on it) the native system sends WM_KILLFOCUS and then FOCUS_LOST is posted. As result the "another JRadioButton" becomes the last opposite component (DKFM.realOppositeComponentWR) that changes the behavior of the restoring focus mechanism.
19-09-2007

EVALUATION Approximately, the problem looks as follows. When ENTER is pressed in the "Find" modal dialog, its components are disabled at first. The focus owner is one of the JRadioButton components. When it gets disabled it initiates focus auto-transfer. Focus is requested to some other JRadioButton. When the appropriate FOCUS_GAINED event is dispatched by the DKFM that JRadioButton appears to be disabled as well. (I suppose that it gets disabled in the period of time after the focus is requested but before the FOCUS_GAINED is dispatched). DKFM rejects this FOCUS_GAINED event on a disabled component and initiates the focus restoring mechanism. By this time, DKFM.realOppositeComponentWR and the most recent focus owner equal the original focus owner (JRadioButton). It's selected as a candidate to restore focus to. Focus is requested on it and then is dispatched by DKFM as well. After that the restoring procedure is repeated and all goes into endless loop. The "Find" dialog is not disposed while this loop is in progress (not clear why, perhaps it waits for some event). Anyway, an endless focus loop shouldn't happen. There're two possible solutions: 1. Allow DKFM to accept FOCUS_GAIED on a disabled component. 2. Prevent focus from being restored to the same component. Applying the 1st approach breaks focus in Netbeans. When I start it and when it loads the "Source Code" tab it's not possible to edit the source code. I suppose that this is due to Netbeans strongly relies on our current focus behavior. To say the truth, the Focus Spec states that a disabled component can be the focus owner. That is, we violate our own spec... =( The second approach works fine.
19-09-2007

EVALUATION Stack traces show some focus-related code at the top of stack.
05-09-2007