-
Bug
-
Resolution: Unresolved
-
P4
-
7u51, 8, 9
-
None
-
generic
-
linux
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.
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.
- relates to
-
JDK-8024061 Exception thrown when drag and drop between two components is executed quickly
-
- Resolved
-