Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8040248

Drag and drop between two components fails if performed quickly

    Details

    • Type: Bug
    • Status: Open
    • Priority: P4
    • Resolution: Unresolved
    • Affects Version/s: 7u51, 8, 9
    • Fix Version/s: tbd
    • Component/s: client-libs
    • Labels:
      None
    • Subcomponent:
    • CPU:
      generic
    • OS:
      linux

      Description

      Assume user attemps a drag-and-drop operation between two components inside one JRE. So DataFlavor.javaJVMLocalObjectMimeType is used, and the transferable is local to the JVM.

      In such case the transferable is stored to a static variable in SunDropTargetContextPeer.setCurrentJVMLocalSourceTransferable(). When processEnterMessage() is handled, its value is copied to instance variable "local". The instance variable is cleaned by processExitMessage(), the static variable is cleared by SunDragSourceContextPeer.cleanup().

      If drag-and-drop operation is performed quickly, SunDragSourceContextPeer.cleanup() is called when mouse button is released and *before* processEnterMessage() is called. So when EDT finally handles MOUSE_ENTERED event and DropTargetListener.dragEnter() gets called, "local" transferable is already null. The listener tries to get the data from the transferable:
      DropTargetDragEvent.getTransferable(), and then
      Transferable.getTransferData(dataFlavor).

      The dataFlavor has MIME type of DataFlavor.javaJVMLocalObjectMimeType, and SunDropTargetContextPeer.currentJVMLocalSourceTransferable is already cleared. The representationClass field of the DataFlavor object is set to java.io.InputStream.class. So when SunDropTargetContextPeer.getNativeData() executes it tries to cast the data object to java.io.InputStream to deserialize the data but fails with the exception:
      java.lang.ClassCastException: JDK8024061$DropObject cannot be cast to java.io.InputStream
      at sun.awt.datatransfer.DataTransferer.translateTransferable(DataTransferer.java:1368)
      at sun.awt.datatransfer.DataTransferer$6.run(DataTransferer.java:2323)
      at sun.awt.datatransfer.DataTransferer.processDataConversionRequests(DataTransferer.java:2380)
      at sun.awt.X11.XSelection.waitForSelectionNotify(XSelection.java:179)
      at sun.awt.X11.XSelection.getData(XSelection.java:295)
      at sun.awt.X11.XDnDDropTargetProtocol.getData(XDnDDropTargetProtocol.java:859)
      at sun.awt.X11.XDropTargetContextPeer.getNativeData(XDropTargetContextPeer.java:151)
      at sun.awt.dnd.SunDropTargetContextPeer.getTransferData(SunDropTargetContextPeer.java:263)
      at sun.awt.datatransfer.TransferableProxy.getTransferData(TransferableProxy.java:73)
      at java.awt.dnd.DropTargetContext$TransferableProxy.getTransferData(DropTargetContext.java:376)
      at JDK8024061$DnDPanel$3.dragEnter(JDK8024061.java:200)
      at java.awt.dnd.DropTarget.dragEnter(DropTarget.java:357)
      at sun.awt.dnd.SunDropTargetContextPeer.processEnterMessage(SunDropTargetContextPeer.java:330)
      at sun.awt.X11.XDropTargetContextPeer.processEnterMessage(XDropTargetContextPeer.java:165)
      at sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchEnterEvent(SunDropTargetContextPeer.java:798)
      at sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchEvent(SunDropTargetContextPeer.java:766)
      at sun.awt.dnd.SunDropTargetEvent.dispatch(SunDropTargetEvent.java:48)
      at java.awt.Component.dispatchEventImpl(Component.java:4716)
      at java.awt.Container.dispatchEventImpl(Container.java:2287)
      at java.awt.Component.dispatchEvent(Component.java:4687)
      at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
      at java.awt.LightweightDispatcher.trackMouseEnterExit(Container.java:4620)
      at java.awt.LightweightDispatcher.processDropTargetEvent(Container.java:4558)
      at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4417)
      at java.awt.Container.dispatchEventImpl(Container.java:2273)
      at java.awt.Window.dispatchEventImpl(Window.java:2719)
      at java.awt.Component.dispatchEvent(Component.java:4687)
      at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
      at java.awt.EventQueue.access$200(EventQueue.java:103)
      at java.awt.EventQueue$3.run(EventQueue.java:694)
      at java.awt.EventQueue$3.run(EventQueue.java:692)
      at java.security.AccessController.doPrivileged(Native Method)
      at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
      at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
      at java.awt.EventQueue$4.run(EventQueue.java:708)
      at java.awt.EventQueue$4.run(EventQueue.java:706)
      at java.security.AccessController.doPrivileged(Native Method)
      at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
      at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
      at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
      at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
      at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
      at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

      This exception is caught internally, and IOException is thrown as it failed to get the data:
      java.io.IOException: Owner failed to convert data
      at sun.awt.X11.XSelection.validateDataGetter(XSelection.java:444)
      at sun.awt.X11.XSelection.getData(XSelection.java:305)
      at sun.awt.X11.XDnDDropTargetProtocol.getData(XDnDDropTargetProtocol.java:859)
      at sun.awt.X11.XDropTargetContextPeer.getNativeData(XDropTargetContextPeer.java:151)
      at sun.awt.dnd.SunDropTargetContextPeer.getTransferData(SunDropTargetContextPeer.java:263)
      at sun.awt.datatransfer.TransferableProxy.getTransferData(TransferableProxy.java:73)
      at java.awt.dnd.DropTargetContext$TransferableProxy.getTransferData(DropTargetContext.java:376)
      at JDK8024061$DnDPanel$3.dragEnter(JDK8024061.java:200)
      at java.awt.dnd.DropTarget.dragEnter(DropTarget.java:357)
      at sun.awt.dnd.SunDropTargetContextPeer.processEnterMessage(SunDropTargetContextPeer.java:330)
      at sun.awt.X11.XDropTargetContextPeer.processEnterMessage(XDropTargetContextPeer.java:165)
      at sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchEnterEvent(SunDropTargetContextPeer.java:798)
      at sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchEvent(SunDropTargetContextPeer.java:766)


      At the same time, no IO should have occurred because a local source was dragged, so this exception is rather unexpected.


      What actually happens is that native drag-and-drop operation completed already whereas this drag-and-drop operation on EDT didn't even started yet.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                aivanov Alexey Ivanov
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated: