United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-4531693 Deadlock while showing a modal dialog from inkoveAndWait().
JDK-4531693 : Deadlock while showing a modal dialog from inkoveAndWait().

Details
Type:
Bug
Submit Date:
2001-11-27
Status:
Resolved
Updated Date:
2003-03-18
Project Name:
JDK
Resolved Date:
2002-08-22
Component:
client-libs
OS:
solaris_9,solaris_8,windows_nt,linux,windows_2000
Sub-Component:
java.awt
CPU:
x86,sparc
Priority:
P4
Resolution:
Fixed
Affected Versions:
1.2.1,1.3.1,1.4.0,1.4.1
Fixed Versions:
1.4.1_03 (03)

Related Reports
Backport:
Duplicate:
Duplicate:
Duplicate:
Duplicate:
Duplicate:
Duplicate:
Duplicate:
Relates:
Relates:
Relates:
Relates:
Relates:
Relates:
Relates:

Sub Tasks

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
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
                                     
2002-03-04
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


======================================================================
                                     
2004-08-24
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


                                     
2004-08-24



Hardware and Software, Engineered to Work Together