United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-7128738 dragged dialog freezes system on dispose
JDK-7128738 : dragged dialog freezes system on dispose

Details
Type:
Bug
Submit Date:
2012-01-10
Status:
Resolved
Updated Date:
2012-04-17
Project Name:
JDK
Resolved Date:
2012-04-17
Component:
client-libs
OS:
windows_xp
Sub-Component:
java.awt
CPU:
x86
Priority:
P4
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:
7u6 (b06)

Related Reports
Backport:

Sub Tasks

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

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.
                                     
2012-02-01
EVALUATION

The problem is reproducible with jdk7 build 147.
                                     
2012-02-01
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();
    }
}
                                     
2012-02-01
EVALUATION

The problem is not reproducible with jdk 6u14.
                                     
2012-02-01
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.
                                     
2012-03-07
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.
                                     
2012-03-13



Hardware and Software, Engineered to Work Together