JDK-8262446 : DragAndDrop hangs on Windows
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 8u281,11.0.10,15.0.2,16
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows
  • CPU: x86_64
  • Submitted: 2021-02-23
  • Updated: 2021-10-05
  • Resolved: 2021-03-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11 JDK 8 Other
11.0.12Fixed 8u301Fixed openjdk8u302Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
Windows x64

A DESCRIPTION OF THE PROBLEM :
Dragging files from Windows Explorer to a Java application hangs. Not each time but very often.
I have implemented a DroppableDesktopPane (see source code) and dropping a file on that DesktopPane sometimes hangs (very often).
This issue is new with JDK 15.0.2 and JDK 11.0.10. It is working fine with the previous release JDK 15.0.1 and JDK 11.0.9.

REGRESSION : Last worked in version 15.0.1, 11.0.9

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Drag a file on the DroppableDesktopPane.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No hanging
ACTUAL -
Application hangs. Stack trace:
UPSEClient15 [Java Application]	
	StartUpFrame at localhost:64016 (Suspended)	
		Thread [Timer-0] (Suspended)	
			waiting for: TaskQueue  (id=40)	
			Object.wait(long) line: not available [native method]	
			TaskQueue(Object).wait() line: 321	
			TimerThread.mainLoop() line: 527	
			TimerThread.run() line: 506	
		Thread [AWT-EventQueue-0] (Suspended)	
			WInputMethod.openCandidateWindow(WComponentPeer, int, int) line: not available [native method]	
			WInputMethod$1.run() line: 622	
			InvocationEvent.dispatch() line: 316	
			EventQueue.dispatchEventImpl(AWTEvent, Object) line: 770	
			EventQueue$4.run() line: 721	
			EventQueue$4.run() line: 715	
			AccessController.executePrivileged(PrivilegedAction<T>, AccessControlContext, Class<?>) line: 753	
			AccessController.doPrivileged(PrivilegedAction<T>, AccessControlContext) line: 391	
			ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(PrivilegedAction<T>, AccessControlContext, AccessControlContext) line: 85	
			ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(PrivilegedAction<T>, AccessControlContext) line: 95	
			EventQueue$5.run() line: 745	
			EventQueue$5.run() line: 743	
			AccessController.executePrivileged(PrivilegedAction<T>, AccessControlContext, Class<?>) line: 753	
			AccessController.doPrivileged(PrivilegedAction<T>, AccessControlContext) line: 391	
			ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(PrivilegedAction<T>, AccessControlContext, AccessControlContext) line: 85	
			EventQueue.dispatchEvent(AWTEvent) line: 742	
			EventDispatchThread.pumpOneEventForFilters(int) line: 203	
			EventDispatchThread.pumpEventsForFilter(int, Conditional, EventFilter) line: 124	
			EventDispatchThread.pumpEventsForHierarchy(int, Conditional, Component) line: 113	
			EventDispatchThread.pumpEvents(int, Conditional) line: 109	
			EventDispatchThread.pumpEvents(Conditional) line: 101	
			EventDispatchThread.run() line: 90	
		Thread [DestroyJavaVM] (Suspended)	
		Daemon Thread [mysql-cj-abandoned-connection-cleanup] (Suspended)	
			waiting for: ReferenceQueue$Lock  (id=38)	
			Object.wait(long) line: not available [native method]	
			ReferenceQueue<T>.remove(long) line: 155	
			AbandonedConnectionCleanupThread.run() line: 91	
			ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1130	
			ThreadPoolExecutor$Worker.run() line: 630	
			Thread.run() line: 832	
		Thread [Thread-2] (Suspended)	
			owns: BufferedInputStream  (id=39)	
			SocketDispatcher.read0(FileDescriptor, long, int) line: not available [native method]	
			SocketDispatcher.read(FileDescriptor, long, int) line: 46	
			NioSocketImpl.tryRead(FileDescriptor, byte[], int, int) line: 261	
			NioSocketImpl.implRead(byte[], int, int) line: 312	
			NioSocketImpl.read(byte[], int, int) line: 350	
			NioSocketImpl$1.read(byte[], int, int) line: 803	
			Socket$SocketInputStream.read(byte[], int, int) line: 981	
			BufferedInputStream.fill() line: 244	
			BufferedInputStream.read() line: 263	
			DataInputStream.readInt() line: 391	
			TCPThread.run() line: 311	
		Daemon System Thread [Reference Handler] (Suspended)	
			Reference<T>.waitForReferencePendingList() line: not available [native method]	
			Reference<T>.processPendingReferences() line: 241	
			Reference$ReferenceHandler.run() line: 213	
		Daemon System Thread [Finalizer] (Suspended)	
			waiting for: ReferenceQueue$Lock  (id=41)	
			Object.wait(long) line: not available [native method]	
			ReferenceQueue<T>.remove(long) line: 155	
			ReferenceQueue<T>.remove() line: 176	
			Finalizer$FinalizerThread.run() line: 170	
		Daemon System Thread [Signal Dispatcher] (Suspended)	
		Daemon System Thread [Attach Listener] (Suspended)	
		Daemon System Thread [Common-Cleaner] (Suspended)	
			waiting for: ReferenceQueue$Lock  (id=42)	
			Object.wait(long) line: not available [native method]	
			ReferenceQueue<T>.remove(long) line: 155	
			CleanerImpl.run() line: 148	
			InnocuousThread(Thread).run() line: 832	
			InnocuousThread.run() line: 134	
		Daemon System Thread [Notification Thread] (Suspended)	
		Daemon System Thread [Java2D Disposer] (Suspended)	
			waiting for: ReferenceQueue$Lock  (id=43)	
			Object.wait(long) line: not available [native method]	
			ReferenceQueue<T>.remove(long) line: 155	
			ReferenceQueue<T>.remove() line: 176	
			Disposer.run() line: 144	
			Thread.run() line: 832	
		System Thread [AWT-Shutdown] (Suspended)	
			waiting for: Object  (id=44)	
			Object.wait(long) line: not available [native method]	
			Object.wait() line: 321	
			AWTAutoShutdown.run() line: 291	
			Thread.run() line: 832	
		Daemon System Thread [AWT-Windows] (Suspended)	
			WToolkitThreadBlockedHandler.startSecondaryEventLoop() line: not available [native method]	
			WToolkitThreadBlockedHandler.enter() line: 508	
			WDropTargetContextPeer(SunDropTargetContextPeer).postDropTargetEvent(Component, int, int, int, int, long[], long, int, boolean) line: 593	
			WDropTargetContextPeer(SunDropTargetContextPeer).handleEnterMessage(Component, int, int, int, int, long[], long) line: 302	
			WToolkit.eventLoop() line: not available [native method]	
			WToolkit.run() line: 361	
			Thread.run() line: 832	
		Daemon System Thread [TimerQueue] (Suspended)	
			Unsafe.park(boolean, long) line: not available [native method]	
			LockSupport.park() line: 341	
			AbstractQueuedSynchronizer$ConditionNode.block() line: 505	
			ForkJoinPool.managedBlock(ForkJoinPool$ManagedBlocker) line: 3137	
			AbstractQueuedSynchronizer$ConditionObject.await() line: 1614	
			DelayQueue<E>.take() line: 217	
			TimerQueue.run() line: 171	
			Thread.run() line: 832	
	C:\Program Files\Java\jdk-15.0.2\bin\javaw.exe (23 Feb 2021, 06:27:09)	


---------- BEGIN SOURCE ----------
/*
		A JDesktopPane which support Drag&Drop.
*/

import java.io.*;
import java.awt.dnd.*;
import java.awt.datatransfer.*;
import java.util.*;


public class DroppableDesktopPane extends javax.swing.JDesktopPane implements DropTargetListener
{
	private static final long serialVersionUID = 1L;
	
	DropTarget  dropTarget;
    MainFrame   mFrame;

    public DroppableDesktopPane(MainFrame mf)
    {
        super();
        mFrame = mf;
        dropTarget = new DropTarget(this, this);
    }


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

	public void dragExit(DropTargetEvent e)
	{

	}

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

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

	public synchronized void drop(DropTargetDropEvent e)
	{
	    try
	    {
			DataFlavor uriListFlavor = new DataFlavor("text/uri-list;class=java.lang.String");
	        Transferable tr = e.getTransferable();

	        if (tr.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
	        {
	            e.acceptDrop(DnDConstants.ACTION_COPY);
	            java.util.List<?> fileList = (java.util.List<?>)tr.getTransferData(DataFlavor.javaFileListFlavor);

	            Iterator<?> it = fileList.iterator();
	            while (it.hasNext())
	            {
	                File file = (File)it.next();
	                if (file != null)
	                    mFrame.doOpen(file);
	            }
	            e.getDropTargetContext().dropComplete(true);
	        }
			else if (tr.isDataFlavorSupported(uriListFlavor))  // Linux java bug 4899516: drop doesn't give a list of file
			{
				e.acceptDrop(DnDConstants.ACTION_COPY);
				String data = (String)tr.getTransferData(uriListFlavor);
				java.util.List<?> fileList = textURIListToFileList(data);

				Iterator<?> it = fileList.iterator();
				while (it.hasNext())
				{
					File file = (File)it.next();
					// open the file
				}
				e.getDropTargetContext().dropComplete(true);
			}
	        else
	            e.rejectDrop();
	    }
	    catch (IOException exio)
	    {
	        e.rejectDrop();
	    }
	    catch (UnsupportedFlavorException ex)
	    {
	        e.rejectDrop();
	    }
		catch (ClassNotFoundException ex2)
		{
			e.rejectDrop();
		}
	}


	private static java.util.List<File> textURIListToFileList(String data)
	{
		java.util.List<File> list = new java.util.ArrayList<File>(1);
		for (java.util.StringTokenizer st = new java.util.StringTokenizer(data, "\r\n"); st.hasMoreTokens();)
		{
			String s = st.nextToken();
			if (s.startsWith("#"))
			{
				// the line is a comment (as per the RFC 2483)
				continue;
			}
			try
			{
				java.net.URI uri = new java.net.URI(s);
				java.io.File file = new java.io.File(uri);
				list.add(file);
			} catch (java.net.URISyntaxException e)
			{
				// malformed URI
			} catch (IllegalArgumentException e)
			{
				// the URI is not a valid 'file:' URI
			}
		}
		return list;
	}

}

---------- END SOURCE ----------

FREQUENCY : often



Comments
Fix Request (8u): Backport to 8u requested because it is a part of 8u301-oracle. 11u patch applies cleanly after the path change. 8u exported commit: https://cr.openjdk.java.net/~akasko/jdk8u/8262446/8262446_8u.changeset Testing: checked that attached TopLevelTransferHandlerDemo.java hangs without the patch and doesn't hang with patch applied.
05-05-2021

Fix request (15u): backporting as follow-up to 8232114. Applies clean.
06-04-2021

Fix Request (11u) Should get backported for parity with 11.0.12-oracle. Applies cleanly except Copyright year change.
16-03-2021

Fix Request (16u) - Justification: The changes fix the regression introduced by JDK-8232114 - Risk Analysis: Low, small changes in awt_DnDDT.cpp - Testing: The fix may be verified using the test attached to the bug (see steps to reproduce above) The patch from jdk-dev (17) applies cleanly to 16u.
09-03-2021

Changeset: bf9b74d1 Author: Dmitry Markov <dmarkov@openjdk.org> Date: 2021-03-08 16:38:21 +0000 URL: https://git.openjdk.java.net/jdk/commit/bf9b74d1
08-03-2021

The IME functions and the DND operation must be executed on the toolkit thread. If the DND operation is in progress, the IME API is invoked via SendMessage() call inside InvokeInputMethodFunction() to avoid a hang. The flag isInDoDragDropLoop indicates whether the DND takes place or not. The flag works properly if the DND is performed between two Java windows. However if anything is dragged from native app, (e.g. Windows FileExplorer) to Java the flag is NOT set. That’s the root cause of the hang. Fix: Introduce a new flag to indicate DND operation between Java and native app.
04-03-2021

It looks like the failure is triggered by JDK-8232114
04-03-2021

I could not reproduce the issue on Windows 10 using JDK 8u281-b01, 11.0.10-b08, 16-b30 and 17. I used the following procedure: 1. Run TopLevelTransferHandlerDemo app attached to the bug 2. Drag a text file from the FileExplorer to the app I repeated the steps above many times but the app kept woking, no hang observed. [~pnarayanaswa] Could you provide me with the details steps to replicate the problem, please?
01-03-2021

Looks like a duplicate of JDK-8261231
26-02-2021

Checked with attached testcase in Windows 10, Issue is reproducible, test app hangs and observed regression in 8u281, 11.0.10, 15.0.2. Test Result: ========= JDK 8u271: Pass JDK 8u281, b01: Fail JDK 11.0.9: Pass JDK 11.0.10, b01: Fail JDK 15.0.1: Pass JDK 15.0.2, b01: Fail JDK 16ea: Fail
26-02-2021