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

Drag and drop between two components fails if performed quickly

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P4
    • tbd
    • 7u51, 8, 9
    • client-libs
    • None
    • generic
    • 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

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

              Dates

                Created:
                Updated: