JDK-4531693 : Deadlock while showing a modal dialog from inkoveAndWait().
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.2.1,1.3.1,1.4.0,1.4.1
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS:
    linux,solaris_8,solaris_9,windows_nt,windows_2000 linux,solaris_8,solaris_9,windows_nt,windows_2000
  • CPU: x86,sparc
  • Submitted: 2001-11-27
  • Updated: 2003-03-18
  • Resolved: 2002-08-22
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.
Other Other
1.4.1_03 03Fixed 1.4.2Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Under JDK 1.4 rc2 I got following thread dump showing deadlock. The same code
works well under JDK 1.3.

Original: http://xml.netbeans.org/issues/show_bug.cgi?id=17992

This thread showed modal customizer dialog.

"org.netbeans.core.ModuleActions-3" daemon prio=1 tid=0x0x84f43a8 nid=0x55ca waiting on monitor [bcfff000..bcfff8ac]
        at java.lang.Object.wait(Native Method)
        - waiting on <0x44260300> (a java.awt.EventQueue$1$AWTInvocationLock)
        at java.lang.Object.wait(Object.java:429)
        at java.awt.EventQueue.invokeAndWait(EventQueue.java:797)
        - locked <0x44260300> (a java.awt.EventQueue$1$AWTInvocationLock)
        at org.openide.util.Mutex.doEventAccess(Mutex.java:933)
        at org.openide.util.Mutex.readAccess(Mutex.java:162)
        at org.netbeans.core.NbNodeOperation.customize(NbNodeOperation.java:126)
        at org.openide.actions.CustomizeAction$CustomizationInvoker.run(CustomizeAction.java:116)
        at org.openide.actions.CustomizeAction.performAction(CustomizeAction.java:44)
        at org.openide.util.actions.NodeAction.performAction(NodeAction.java:180)
        at org.openide.util.actions.NodeAction.actionPerformed(NodeAction.java:171)
        at org.netbeans.core.ModuleActions$1.run(ModuleActions.java:105)
        at org.openide.util.Task.run(Task.java:152)
        at org.openide.util.RequestProcessor$ProcessorThread.run(RequestProcessor.java:622)


The customizer dialog want to show a modal dialog:

"AWT-EventQueue-0" prio=1 tid=0x0x823f200 nid=0x558b waiting on monitor [bdffd000..bdfff8ac]
        at java.lang.Object.wait(Native Method)
        - waiting on <0x448b3340> (a java.awt.EventQueue)
        at java.lang.Object.wait(Object.java:429)
        at java.awt.EventQueue.getNextEvent(EventQueue.java:364)
        - locked <0x448b3340> (a java.awt.EventQueue)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:158)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:147)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:141)
        at java.awt.SequencedEvent.dispatch(SequencedEvent.java:75)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:446)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:193)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:147)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:137)
        at java.awt.Dialog.show(Dialog.java:527)
        at org.netbeans.core.NbPresenter.superShow(NbPresenter.java:589)
        at org.netbeans.core.NbPresenter.run(NbPresenter.java:612)
        at org.openide.util.Mutex.doEventAccess(Mutex.java:922)
        at org.openide.util.Mutex.readAccess(Mutex.java:162)
        at org.netbeans.core.NbPresenter.show(NbPresenter.java:593)
        at java.awt.Component.show(Component.java:1131)
        at java.awt.Component.setVisible(Component.java:1086)
        at org.netbeans.core.NbTopManager$2.run(NbTopManager.java:524)
        at org.openide.util.Mutex.doEventAccess(Mutex.java:922)
        at org.openide.util.Mutex.readAccess(Mutex.java:162)
        at org.netbeans.core.NbTopManager.notify(NbTopManager.java:503)
        at org.netbeans.modules.xml.tax.AbstractUtil.notifyWarning(AbstractUtil.java:96)
        at org.netbeans.modules.xml.tax.AbstractUtil.notifyTreeException(AbstractUtil.java:89)
        at org.netbeans.modules.xml.tax.beans.customizer.TreeAttlistDeclAttributeDefCustomizer.updateAttributeDefEnumeratedType(TreeAttlistDeclAttributeDefCustomizer.java:13)
        at org.netbeans.modules.xml.tax.beans.customizer.TreeAttlistDeclAttributeDefCustomizer.enumeratedFieldFocusLost(TreeAttlistDeclAttributeDefCustomizer.java:441)
        at org.netbeans.modules.xml.tax.beans.customizer.TreeAttlistDeclAttributeDefCustomizer.access$500(TreeAttlistDeclAttributeDefCustomizer.java:25)
        at org.netbeans.modules.xml.tax.beans.customizer.TreeAttlistDeclAttributeDefCustomizer$6.focusLost(TreeAttlistDeclAttributeDefCustomizer.java:327)
        at java.awt.AWTEventMulticaster.focusLost(AWTEventMulticaster.java:171)
        at java.awt.Component.processFocusEvent(Component.java:4930)
        at java.awt.Component.processEvent(Component.java:4812)
        at java.awt.Container.processEvent(Container.java:1383)
        at java.awt.Component.dispatchEventImpl(Component.java:3529)
        at java.awt.Container.dispatchEventImpl(Container.java:1440)
        at java.awt.Component.dispatchEvent(Component.java:3370)
        at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1703)
        at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:712)
        at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:445)
        at java.awt.Component.dispatchEventImpl(Component.java:3399)
        at java.awt.Container.dispatchEventImpl(Container.java:1440)
        at java.awt.Component.dispatchEvent(Component.java:3370)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:448)
        at java.awt.SentEvent.dispatch(SentEvent.java:53)
        at java.awt.DefaultKeyboardFocusManager$DefaultKeyboardFocusManagerSentEvent.dispatch(DefaultKeyboardFocusManager.java:143)
        at java.awt.DefaultKeyboardFocusManager.sendMessage(DefaultKeyboardFocusManager.java:167)
        at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:497)
        at java.awt.Component.dispatchEventImpl(Component.java:3399)
        at java.awt.Container.dispatchEventImpl(Container.java:1440)
        at java.awt.Window.dispatchEventImpl(Window.java:1569)
        at java.awt.Component.dispatchEvent(Component.java:3370)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:448)
        at java.awt.SentEvent.dispatch(SentEvent.java:53)
        at java.awt.DefaultKeyboardFocusManager$DefaultKeyboardFocusManagerSentEvent.dispatch(DefaultKeyboardFocusManager.java:143)
        at java.awt.DefaultKeyboardFocusManager.sendMessage(DefaultKeyboardFocusManager.java:167)
        at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:223)
        at java.awt.Component.dispatchEventImpl(Component.java:3399)
        at java.awt.Container.dispatchEventImpl(Container.java:1440)
        at java.awt.Window.dispatchEventImpl(Window.java:1569)
        at java.awt.Component.dispatchEvent(Component.java:3370)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:448)
        at java.awt.SequencedEvent.dispatch(SequencedEvent.java:108)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:446)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:193)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:147)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:137)
        at java.awt.Dialog.show(Dialog.java:527)
        at org.netbeans.core.NbPresenter.superShow(NbPresenter.java:589)
        at org.netbeans.core.NbPresenter.run(NbPresenter.java:612)
        at org.openide.util.Mutex.doEventAccess(Mutex.java:922)
        at org.openide.util.Mutex.readAccess(Mutex.java:162)
        at org.netbeans.core.NbPresenter.show(NbPresenter.java:593)
        at java.awt.Component.show(Component.java:1131)
        at java.awt.Component.setVisible(Component.java:1086)
        at org.netbeans.core.NbTopManager$2.run(NbTopManager.java:524)
        at org.openide.util.Mutex.doEventAccess(Mutex.java:922)
        at org.openide.util.Mutex.readAccess(Mutex.java:162)
        at org.netbeans.core.NbTopManager.notify(NbTopManager.java:503)
        at org.netbeans.modules.xml.tax.AbstractUtil.notifyWarning(AbstractUtil.java:96)
        at org.netbeans.modules.xml.tax.AbstractUtil.notifyTreeException(AbstractUtil.java:89)
        at org.netbeans.modules.xml.tax.beans.customizer.TreeAttlistDeclAttributeDefCustomizer.updateAttributeDefType(TreeAttlistDeclAttributeDefCustomizer.java:118)
        at org.netbeans.modules.xml.tax.beans.customizer.TreeAttlistDeclAttributeDefCustomizer.typeFieldFocusLost(TreeAttlistDeclAttributeDefCustomizer.java:446)
        at org.netbeans.modules.xml.tax.beans.customizer.TreeAttlistDeclAttributeDefCustomizer.access$300(TreeAttlistDeclAttributeDefCustomizer.java:25)
        at org.netbeans.modules.xml.tax.beans.customizer.TreeAttlistDeclAttributeDefCustomizer$4.focusLost(TreeAttlistDeclAttributeDefCustomizer.java:296)
        at java.awt.AWTEventMulticaster.focusLost(AWTEventMulticaster.java:171)
        at java.awt.Component.processFocusEvent(Component.java:4930)
        at java.awt.Component.processEvent(Component.java:4812)
        at java.awt.Container.processEvent(Container.java:1383)
        at java.awt.Component.dispatchEventImpl(Component.java:3529)
        at java.awt.Container.dispatchEventImpl(Container.java:1440)
        at java.awt.Component.dispatchEvent(Component.java:3370)
        at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1703)
        at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:712)
        at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:445)
        at java.awt.Component.dispatchEventImpl(Component.java:3399)
        at java.awt.Container.dispatchEventImpl(Container.java:1440)
        at java.awt.Component.dispatchEvent(Component.java:3370)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:448)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:193)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:147)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:137)
        at java.awt.Dialog.show(Dialog.java:527)
        at org.netbeans.core.NbPresenter.superShow(NbPresenter.java:589)
        at org.netbeans.core.NbPresenter.run(NbPresenter.java:612)
        at org.openide.util.Mutex.doEventAccess(Mutex.java:922)
        at org.openide.util.Mutex.readAccess(Mutex.java:162)
        at org.netbeans.core.NbPresenter.show(NbPresenter.java:593)
        at org.netbeans.core.NbNodeOperation$2.run(NbNodeOperation.java:146)
        at org.openide.util.Mutex$1.run(Mutex.java:936)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:174)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:446)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:193)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:147)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:141)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:133)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:101)


###@###.### 2001-11-28

It sounds to be focus related when showing a dilaog from focusLost(). The dialog is not shown properly. (May be it want to call back another focus lost.) A simple case attached. 

=============================================================  

Here is the test case from the attachments.  
I commented out the package statement.  

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

// package bt4531.s693;

import java.awt.*;

import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;

/**
 * Test that under JDK 1.4 b87 crashes as the second dialog is not
 * shown properly. It works fine under JDK 1.3.
 * <p>
 * It sounds that it is focus related as I was not able to reproduce it
 * on a mouse event.
 *
 * @author  Petr Kuzel
 */
public class DialogTest {

    /** Creates a new instance of DialogTest */
    public DialogTest() {
    }

    /**
    * @param args the command line arguments
    */
    public static void main (String args[]) throws Exception {

        final JFrame f = new JFrame("Test 4531693");        
        f.setSize(300, 300);
        f.show();
        
        SwingUtilities.invokeAndWait( new Runnable() {
            public void run() {
                JDialog d = new XDialog(f, "L1 dialog", true);
                d.setSize(200,200);
                d.getContentPane().add(new JLabel("L1 dialog"));
                d.show();
            }
        });
        
        System.err.println("Done");
        System.exit(0);  //kill AWT thread
    }

    private static class XDialog extends JDialog {
        
        private final Frame f;
        
        public XDialog(Frame f, String t, boolean b) {
            super(f, t, b);
            this.f = f;
        }
        
        public void show() {

            addFocusListener(new FocusAdapter() {
                public void focusLost(FocusEvent e) {
                    JDialog d = new JDialog(XDialog.this, "L2 dialog", true);
                    d.setSize(100, 100);
                    d.getContentPane().add(new JLabel("L2 dialog"));
                    d.show();
                }
                
            });
            
            super.show();
            
        }
    }
}


###@###.### 2001-11-29



###@###.### 2002-03-19
------------------------------

CAP member had reported the same problem and this problem is serious enough 
that they might have to move back to 1.3.1.

Their EventQueue got stuck, resulting in an application that wont redraw nor
respond to the user but that is otherwise alive. Attached their stack trace:

"AWT-EventQueue-0" prio=7 tid=0x0ABD1BB0 nid=0x8d8 waiting on monitor
[afdf000..afdfdb4]
        at java.lang.Object.wait(Native Method)
        - waiting on <02F3C498> (a java.awt.EventQueue)
        at java.lang.Object.wait(Object.java:426)
        at java.awt.EventQueue.getNextEvent(EventQueue.java:329)
        - locked <02F3C498> (a java.awt.EventQueue)
        at
java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.ja
va:155)
        at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java
:144)
        at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
        at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:130)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:98)


They have had this happen even when modal dialogs are not involved.

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.4.1_03 mantis FIXED IN: 1.4.1_03 mantis INTEGRATED IN: 1.4.1_03 mantis
24-08-2004

SUGGESTED FIX Name: osR10079 Date: 08/02/2002 ------- Dialog.java ------- *** /tmp/sccs.zHaG0I Thu Jul 11 13:23:54 2002 --- Dialog.java Thu Jul 11 13:23:51 2002 *************** *** 533,538 **** --- 533,550 ---- enqueueKeyEvents(time, predictedFocusOwner); if (Toolkit.getEventQueue().isDispatchThread()) { + /* + * dispose SequencedEvent we are dispatching on current + * AppContext, to prevent us from hang. + * + * BugId 4531693 (###@###.###) + */ + SequencedEvent currentSequencedEvent = KeyboardFocusManager. + getCurrentKeyboardFocusManager().getCurrentSequencedEvent(); + if (currentSequencedEvent != null) { + currentSequencedEvent.dispose(); + } + EventDispatchThread dispatchThread = (EventDispatchThread)Thread.currentThread(); dispatchThread.pumpEventsForHierarchy(new Conditional() { ------- KeyboardFocusManager.java ------- *** /tmp/sccs.AHaG0I Thu Jul 11 13:23:54 2002 --- KeyboardFocusManager.java Thu Jul 11 13:17:40 2002 *************** *** 302,307 **** --- 302,325 ---- */ private static AWTPermission replaceKeyboardFocusManagerPermission; + /* + * SequencedEvent which is currently dispatched in AppContext. + */ + transient SequencedEvent currentSequencedEvent = null; + + final void setCurrentSequencedEvent(SequencedEvent current) { + synchronized (SequencedEvent.class) { + assert(current == null || currentSequencedEvent == null); + currentSequencedEvent = current; + } + } + + final SequencedEvent getCurrentSequencedEvent() { + synchronized (SequencedEvent.class) { + return currentSequencedEvent; + } + } + static Set loadFocusTraversalKeys(String propName, String defaultValue, Set targetSet) { String keys = Toolkit.getProperty(propName, defaultValue); ------- SequencedEvent.java ------- *** /tmp/sccs.CHaG0I Thu Jul 11 13:23:54 2002 --- SequencedEvent.java Thu Jul 11 13:14:58 2002 *************** *** 88,93 **** --- 88,95 ---- } if (!disposed) { + KeyboardFocusManager.getCurrentKeyboardFocusManager(). + setCurrentSequencedEvent(this); Toolkit.getEventQueue().dispatchEvent(nested); } } finally { *************** *** 153,159 **** if (disposed) { return; } ! disposed = true; } // Wake myself up if (appContext != null) { --- 155,166 ---- if (disposed) { return; } ! if (KeyboardFocusManager.getCurrentKeyboardFocusManager(). ! getCurrentSequencedEvent() == this) { ! KeyboardFocusManager.getCurrentKeyboardFocusManager(). ! setCurrentSequencedEvent(null); ! } ! disposed = true; } // Wake myself up if (appContext != null) { ###@###.### August 2, 2002 ======================================================================
24-08-2004

EVALUATION Can the submitter please attach a small test case demonstrating the problem. ###@###.### 2001-11-27 Emailed the submitter for a test case and steps to reproduce the bug on Nov. 28, 2001. ###@###.### 2001-11-28 Here are the results of the investigation performed by ###@###.### : Let me describe situation with this problem. In 1.4 we have SequencedEvent, this is a wrapper for events which we want to dispatch in correct order (for now we wrap Focus- and WindowEvents posted from native code). To guarantee correct order of dispatching we keep all undispatched SequencedEvents in one list and if we try to dispatch not first event it waits until all events before it are dispatched or disposed because of their AppContext is disposed. This works ok until user shows modal dialog in handler of the event wrapped by SequencedEvent or generated by KeyboardFocusManager in handler of wrapped event (if we receive FOCUS_GAINED, but focus owner isn't null we generate appropriate FOCUS_LOST and _SEND_ it to focus owner). I've invetigated a few ways to fix exactly this problem (and only it). And only one fixes it. To fix this problem we should remove SequencedEvent from the list of SequensedEvents before dispatching the wrapped event. But this fix has terrible side effect: it breaks correct order of event dispatching. This means it is not acceptable. So we have no partial fix for this problem. And to fix it we have to redesign this part of Focus API (we needed to replace SequencedEvent by something other). I believe now it is too late to do this in Merlin, so i suggest to commit it to Hopper (or Tiger if Hopper is too small for this). I'll defer this until Tiger, since it sounds like much more work is needed than we can do in Merlin, and likely more than we can do in Hopper. ###@###.### 2001-12-04 Name: osR10079 Date: 12/21/2001 The problem is as follows: after focus rearchitecture we post SequencedEvents as wrapper for all Focus- and WindowEvents. When we change focus native code sends SequencedEvent for FOCUS_LOST (SE1). When we receive SE1 we call EventQueue.dispatchEvent() for FOCUS_LOST. In FOCUS_LOST handler user shows modal dialog (on the same thread) and we start secondary event pump. In this pump we receive another SequencedEvent (SE2) (e.g. for WINDOW_GAINED_FOCUS for this new dialog) and try to dispatch it. But SE2 can not be dispatched until SE1 will be completely dispatched. Thus we have a hang. ###@###.### 21 Dec 2001 ====================================================================== Instead of using invokeAndWait(), we can use invokeLater as a worksround to this issue. ###@###.### 2002-03-04 We should consider putting this back early in mantis. ###@###.### 2002-04-05
04-03-2002