JDK-7128738 : dragged dialog freezes system on dispose
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 7
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2012-01-10
  • Updated: 2015-03-03
  • Resolved: 2012-04-17
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 6 JDK 7 JDK 8
6u101Fixed 7u6 b06Fixed 8Fixed
Description
FULL PRODUCT VERSION :
java version "1.7.0_02"
Java(TM) SE Runtime Environment (build 1.7.0_02-b13)
Java HotSpot(TM) Client VM (build 22.0-b10, mixed mode, sharing)

and

java version "1.6.0_29"
Java(TM) SE Runtime Environment (build 1.6.0_29-b11)
Java HotSpot(TM) Client VM (build 20.4-b02, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
and
Microsoft Windows [Version 6.1.7601]


A DESCRIPTION OF THE PROBLEM :
When a JDialog (or JFrame) is being dragged (or just held) with the mouse while dispose() is called, the whole systems seems to freeze.
On a multicore system only one of the cores shows 100% cpu usage, but the windows desktop and all other applications are unresponsive.

The only way out of this state seems to be to ALT-Tab to a different application.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute the code and drag the small dialog (and keep the mouse button pressed) until the dialog disappears.


ACTUAL -
All applications are unresponsive but continue working. E.g. the task manager will show the current CPU usage, but not react to mouse clicks.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javax.swing.JFrame;


public class DialogExecuter extends JFrame {

    public static void main(String[] args) {
        new DialogExecuter();
    }

    public DialogExecuter() {
        this.setSize(800, 800);
        this.setVisible(true);

        Test test = new Test();
        test.start();
    }

    private class Test extends Thread {

        @Override
        public void run() {
            DialogClass dialog = new DialogClass();

            try {
                sleep(5000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            
            // system will lock up when the dialog is dragged while being disposed
            dialog.dispose();
        }
    }

    private class DialogClass extends JFrame {

        public DialogClass() {
            init();
        }

        private void init() {
            setBounds(50, 50, 100, 100);
            setVisible(true);
        }
    }
}

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

Comments
EVALUATION I found the changes made in 6u25 that caused it happens: changeset: 149:91728422fc0b user: vikram date: Thu Oct 28 05:22:49 2010 -0700 summary: 6887981: Exception violation in Java2D Disposer As those changes were required to eliminate the crash we could not revert them.
13-03-2012

EVALUATION It's problem in AWT native code. First of all when clicking Frame's title bar, WM_NCLBUTTONDOWN is sent and then WM_SYSCOMMAND with SC_MOVE. That initates a special message loop creation for Frame's move operation blocking mentioned message handlers. At the same time JFrame.dispose() is called that causes the following sequence: Window.dispose() Window.doDispose() DisposeAction.run() Window.removeNotify() Container.removeNotify() Component.removeNotify() WComponentPeer.dispose() WComponentPeer.disposeImpl() WComponentPeer._dispose() [Native] AwtObject::_Dispose(self) SendMessage(WM_AWT_DISPOSE...) AwtFrame::Dispose() AwtWindow::Dispose() AwtCanvas::Dispose() AwtComponent::Dispose() AwtObject::Dispose() PostMessage(WM_AWT_DELETEOBJECT...) WM_AWT_DELETEOBJECT handler: AwtComponent::CanBeDeleted() returns FALSE because m_MessagesProcessing == 2 (WM_NCLBUTTONDOWN & WM_SYSCOMMAND), so PostMessage(WM_AWT_DELETEOBJECT...) is sent over and over again that increases CPU usage to 100% by Toolkit thread And only when switching to another application, message loop for Frame's moving is finished, WM_SYSCOMMAND & WM_NC_LBUTTONDOWN handles are freed, thus m_MessagesProcessing == 0, reposting of WM_AWT_DELETEOBJECT is stopped and AwtFrame object is deleted. Sending WM_CANCELMODE while hiding the Frame for case when sizing or moving could be one of possible ways to resolve this issue.
07-03-2012

EVALUATION The problem is not reproducible with jdk 6u14.
01-02-2012

EVALUATION The simplest way to reproduce the problem import java.awt.*; public class AwtDialogExecuter extends Frame { public static void main(String[] args) { Frame frame1 = new Frame(); frame1.setVisible(true); Frame frame2 = new Frame(); frame2.setVisible(true); try { Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); } frame2.dispose(); } }
01-02-2012

EVALUATION The problem is reproducible with jdk7 build 147.
01-02-2012

EVALUATION Looks like a grab issue. The problem is not reproducible if I comment out showing of the frame. The problem is reproducible with the latest jdk8 build.
01-02-2012