JDK-4216890 : Swing drag and drop deadlock
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.2.0
  • Priority: P2
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_nt
  • CPU: x86
  • Submitted: 1999-03-03
  • Updated: 1999-11-29
  • Resolved: 1999-11-29
Related Reports
Duplicate :  
Description
import java.awt.*;
import java.awt.event.*;
import java.awt.dnd.*;
import java.awt.datatransfer.*;
import javax.swing.event.*;
import javax.swing.*;
import java.io.*;
import java.util.*;


public class BugDndDeadlock
{


        public static void main(String argv[])
        {
                // Display the Description
                for(int i=0; i<desc.length; i++)
                        System.out.println(desc[i]);
                        

                Frame frame = new Frame("Java-2 Drag/Drop Deadlock Bug");
                BugDndDeadlock c = new BugDndDeadlock(frame);
        }

        private static final String desc[] =
        {
                
                "Usage: java BugDndDeadlock",
                "    This test demonstrates a deadlock problem in Java-2 Drag-Drop.",
                "    Just drag text from one label to another and a deadlock will occur.",
                "    The deadlock is caused by the Label calling setCursor in MOUSE_MOVED",
                "    and can be avoided by removing the call to setCursor."
                
        };


        public BugDndDeadlock(Frame f)
        {
                DraggableLabel north = new DraggableLabel("One");
                DraggableLabel south = new DraggableLabel("Two");
                DraggableLabel east  = new DraggableLabel("Three");
                DraggableLabel west  = new DraggableLabel("Four");
        
                f.add (north, BorderLayout.NORTH);
                f.add (south, BorderLayout.SOUTH);
                f.add (east,  BorderLayout.EAST);
                f.add (west,  BorderLayout.WEST);
                f.setBounds (200, 200, 300, 300);
                f.addWindowListener (new WindowAdapter()
                                                        {
                                                                        public void windowClosing(WindowEvent e)
                                                                        {
                                                                                System.exit(0);
                                                                        }
                                                        });
                f.setVisible (true);
        }

        // ================================================================
        //      This is a Subclass of JLabel that supports drag and drop
        // ================================================================
        class DraggableLabel extends JLabel
        implements DragSourceListener
                         , DragGestureListener
                         , DropTargetListener
        {
        
                
                public DraggableLabel(String s)
                {
                        super (s);
                        DragSource dragSource = new DragSource();
                        dragSource.createDefaultDragGestureRecognizer(this
                                                                                                        , DnDConstants.ACTION_COPY_OR_MOVE
                                                                                                        , this);
                        DropTarget dropTarget = new DropTarget (this, this);
                }

                // This label changes the cursor when the mouse flys over it
                // 
                public void processMouseMotionEvent(MouseEvent e)
                {
                        // Allow Drag/Drop the first crack at mouse events
                        super.processMouseMotionEvent(e);
                        if(!e.isConsumed())
                        {
                                setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
                        }
                }

                public void dragGestureRecognized(DragGestureEvent e)
                {
                        StringSelection transferable = new StringSelection(getText());
                        e.startDrag(DragSource.DefaultCopyDrop, transferable, this);
                }

                public void dragDropEnd (DragSourceDropEvent e)
                {
                        System.out.println("Label: DragDropEnd");
                }
                public void dragEnter (DragSourceDragEvent e){}
                public void dragExit (DragSourceEvent e){}
                public void dragOver (DragSourceDragEvent e){}
                public void dropActionChanged (DragSourceDragEvent e){}
                
                

                public void dragEnter (DropTargetDragEvent e)
                {
                        System.out.println("Entering Drop Target");
                        e.acceptDrag (DnDConstants.ACTION_COPY);
                }

                public void dragExit (DropTargetEvent e)
                {
                        System.out.println("Exiting Drop Target");
                }

                public void dragOver (DropTargetDragEvent e)
                {
                        e.acceptDrag (DnDConstants.ACTION_COPY);
                }


                public void drop (DropTargetDropEvent e)
                {
                        try {
                                Transferable tr = e.getTransferable();
                                if (tr.isDataFlavorSupported (DataFlavor.stringFlavor))
                                {
                                        e.acceptDrop(e.getDropAction());
                                        String s = (String)tr.getTransferData (DataFlavor.stringFlavor);
                                        System.out.println("Accepting Drop of '"+s+"'");
                                        setText(s);
                                        e.dropComplete(true);
                                } else {
                                        System.err.println ("Rejected");
                                        e.rejectDrop();
                                }
                        } catch (IOException io) {
                                io.printStackTrace();
                                e.rejectDrop();
                        } catch (UnsupportedFlavorException ufe){
                                ufe.printStackTrace();
                                e.rejectDrop();
                        }
                }

                public void dropActionChanged(DropTargetDragEvent e)
                {
                }
                
        }


}


/*

Here's the JDB Thread Dump at the time of deadlock

C:\Dev\com\sssw\test\Jdk12>java -version
java version "1.2"
Classic VM (build JDK-1.2-V, native threads)

C:\Dev\com\sssw\test\Jdk12>\jdk1.2\bin\jdb BugDndDeadlock
Initializing jdb...
0xae:class(BugDndDeadlock)
> run
run BugDndDeadlock
running ...
main[1] Usage: java BugDndDeadlock
    This test demonstrates a deadlock problem in Java-2 Drag-Drop.
    Just drag text from one label to another and a deadlock will occur.
    The deadlock is caused by the Label calling setCursor in MOUSE_MOVED
    and can be avoided by removing the call to setCursor.

Current thread "main" died. Execution continuing...
> Entering Drop Target
Exiting Drop Target
Accepting Drop of 'Four'
Label: DragDropEnd
Entering Drop Target
Exiting Drop Target
Entering Drop Target
Exiting Drop Target

> wherei all
AWT-EventQueue-0:
  [1] sun.awt.windows.WComponentPeer.setCursor (native method), pc = -1
  [2] java.awt.Component.setCursor (Component:1759), pc = 16
  [3] java.awt.LightweightDispatcher.retargetMouseEvent (LightweightDispatcher:1953), pc = 156
  [4] java.awt.LightweightDispatcher.trackMouseEnterExit (LightweightDispatcher:1817), pc = 117
  [5] java.awt.LightweightDispatcher.processMouseEvent (LightweightDispatcher:1705), pc = 25
  [6] java.awt.LightweightDispatcher.dispatchEvent (LightweightDispatcher:1645), pc = 40
  [7] java.awt.Container.dispatchEventImpl (Container:1019), pc = 12
  [8] java.awt.Window.dispatchEventImpl (Window:714), pc = 89
  [9] java.awt.Component.dispatchEvent (Component:2289), pc = 2
  [10] java.awt.EventQueue.dispatchEvent (EventQueue:258), pc = 36
  [11] java.awt.EventDispatchThread.run (EventDispatchThread:68), pc = 16

SunToolkit.PostEventQueue-0:
  [1] java.lang.Object.wait (native method), pc = -1
  [2] java.lang.Object.wait (Object:424), pc = 2
  [3] sun.awt.PostEventQueue.run (PostEventQueue:363), pc = 11

AWT-Windows:
  [1] java.lang.Object.wait (native method), pc = -1
  [2] java.lang.Object.wait (Object:424), pc = 2
  [3] sun.awt.windows.WDropTargetContextPeer.handleMotionMessage (WDropTargetContextPeer:698), pc = 107
  [4] sun.awt.windows.WToolkit.eventLoop (native method), pc = -1
  [5] sun.awt.windows.WToolkit.run (WToolkit:134), pc = 26
  [6] java.lang.Thread.run (Thread:479), pc = 11

Screen Updater:
  [1] java.lang.Object.wait (native method), pc = -1
  [2] java.lang.Object.wait (Object:424), pc = 2
  [3] sun.awt.ScreenUpdater.nextEntry (ScreenUpdater:79), pc = 8
  [4] sun.awt.ScreenUpdater.run (ScreenUpdater:99), pc = 6
Thread-2:
  [1] sun.awt.windows.WDragSourceContextPeer.doDragDrop (native method), pc = -1
  [2] sun.awt.windows.WDragSourceContextPeer$1.run (WDragSourceContextPeer$1:163
), pc = 18
>
*/

Comments
EVALUATION ================================================================ jeff.dunn@Eng 1999-07-14 Hopefully this will be fixed with other threading work in kestrel. Unfortunately, there are no resources to apply directly to this bug until the next release. ================================================================
11-06-2004

PUBLIC COMMENTS Swing deadlock bug
10-06-2004