diff --git a/test/jdk/java/awt/dnd/MissedDragEnterTest.java b/test/jdk/java/awt/dnd/MissedDragEnterTest.java
new file mode 100644
index 00000000000..60fc5c3b85f
--- /dev/null
+++ b/test/jdk/java/awt/dnd/MissedDragEnterTest.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.FlowLayout;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DragGestureEvent;
+import java.awt.dnd.DragGestureListener;
+import java.awt.dnd.DragSource;
+import java.awt.dnd.DragSourceDragEvent;
+import java.awt.dnd.DragSourceDropEvent;
+import java.awt.dnd.DragSourceEvent;
+import java.awt.dnd.DragSourceListener;
+import java.awt.dnd.DropTarget;
+import java.awt.dnd.DropTargetContext;
+import java.awt.dnd.DropTargetDragEvent;
+import java.awt.dnd.DropTargetDropEvent;
+import java.awt.dnd.DropTargetEvent;
+import java.awt.dnd.DropTargetListener;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+/*
+  @test
+  @bug 4388802
+  @summary tests that dragEnter() is called on a DropTargetListener if its drop
+           target is associated with a component which initiated the drag
+  @key headful
+  @run main MissedDragEnterTest
+*/
+
+public class MissedDragEnterTest {
+
+    static final int FRAME_ACTIVATION_TIMEOUT = 1000;
+    volatile JFrame frame;
+    volatile DragSourceDropTargetPanel panel;
+    volatile Point p;
+    volatile Dimension d;
+
+    public static void main(String[] args) throws Exception {
+        MissedDragEnterTest test = new MissedDragEnterTest();
+        EventQueue.invokeAndWait(test::init);
+        try {
+            test.start();
+        } finally {
+            EventQueue.invokeAndWait(() -> {
+                if (test.frame != null) {
+                    test.frame.dispose();
+                }
+            });
+        }
+    }
+
+    public void init() {
+        panel = new DragSourceDropTargetPanel();
+        frame = new JFrame();
+        frame.setTitle("MissedDragEnterTest");
+        frame.setLocation(200, 200);
+        frame.getContentPane().add(panel);
+
+        frame.pack();
+        frame.setVisible(true);
+    }
+
+    public void start() throws Exception {
+        Robot robot = new Robot();
+
+        robot.delay(FRAME_ACTIVATION_TIMEOUT);
+        EventQueue.invokeAndWait(() -> {
+            p = panel.getLocationOnScreen();
+            d = panel.getSize();
+        });
+
+        p.translate(d.width / 2, d.height / 2);
+        robot.mouseMove(p.x, p.y);
+        robot.keyPress(KeyEvent.VK_CONTROL);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        for (int i = 0; i < d.width; i++) {
+            p.translate(1, 1);
+            robot.mouseMove(p.x, p.y);
+            robot.delay(10);
+        }
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        robot.keyRelease(KeyEvent.VK_CONTROL);
+
+        EventQueue.invokeAndWait(() -> {
+            if (!panel.getResult()) {
+                throw new RuntimeException("The test failed.");
+            }
+        });
+    }
+}
+
+class DragSourceDropTargetPanel extends JPanel implements DropTargetListener,
+                                                          Serializable,
+                                                          Transferable,
+                                                          DragGestureListener,
+                                                          DragSourceListener {
+    private final DataFlavor dataflavor =
+        new DataFlavor(JPanel.class, "panel");
+    private final Dimension preferredDimension = new Dimension(200, 100);
+    private boolean inside = false;
+    private boolean passed = true;
+
+    public DragSourceDropTargetPanel() {
+        setLayout(new FlowLayout());
+        DragSource ds = DragSource.getDefaultDragSource();
+        ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY,
+                                              this);
+        setDropTarget(new DropTarget(this, this));
+    }
+
+    public void dragGestureRecognized(DragGestureEvent dge) {
+        dge.startDrag(null, this, this);
+    }
+
+    public void dragEnter(DragSourceDragEvent dsde) {}
+
+    public void dragExit(DragSourceEvent dse) {}
+
+    public void dragOver(DragSourceDragEvent dsde) {}
+
+    public void dragDropEnd(DragSourceDropEvent dsde) {}
+
+    public void dropActionChanged(DragSourceDragEvent dsde) {}
+
+    public Object getTransferData(DataFlavor flavor)
+      throws UnsupportedFlavorException, IOException {
+
+        if (!isDataFlavorSupported(flavor)) {
+            throw new UnsupportedFlavorException(flavor);
+        }
+
+        Object retObj = null;
+
+        ByteArrayOutputStream baoStream = new ByteArrayOutputStream();
+        ObjectOutputStream ooStream = new ObjectOutputStream(baoStream);
+        ooStream.writeObject(this);
+
+        ByteArrayInputStream baiStream = new ByteArrayInputStream(baoStream.toByteArray());
+        ObjectInputStream ois = new ObjectInputStream(baiStream);
+        try {
+            retObj = ois.readObject();
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
+            throw new RuntimeException(e.toString());
+        }
+
+        return retObj;
+    }
+
+    public DataFlavor[] getTransferDataFlavors() {
+        return new DataFlavor[] { dataflavor };
+    }
+
+    public boolean isDataFlavorSupported(DataFlavor dflavor) {
+        return dataflavor.equals(dflavor);
+    }
+
+    public Dimension getPreferredSize() {
+        return preferredDimension;
+    }
+
+    public void dragEnter(DropTargetDragEvent dtde) {
+        inside = true;
+    }
+
+    public void dragExit(DropTargetEvent dte) {
+        if (!inside) {
+            passed = false;
+            inside = false;
+            throw new RuntimeException("dragEnter() is not called before dragExit()");
+
+        }
+        inside = false;
+    }
+
+    public void dragOver(DropTargetDragEvent dtde) {
+        if (!inside) {
+            passed = false;
+            throw new RuntimeException("dragEnter() is not called before dragOver()");
+        }
+    }
+
+    public void dropActionChanged(DropTargetDragEvent dtde) {
+    }
+
+    public void drop(DropTargetDropEvent dtde) {
+        DropTargetContext dtc = dtde.getDropTargetContext();
+
+        if ((dtde.getSourceActions() & DnDConstants.ACTION_COPY) != 0) {
+            dtde.acceptDrop(DnDConstants.ACTION_COPY);
+        } else {
+            dtde.rejectDrop();
+        }
+
+        DataFlavor[] dfs = dtde.getCurrentDataFlavors();
+        Component comp = null;
+
+        if (dfs != null && dfs.length >= 1) {
+            Transferable transfer = dtde.getTransferable();
+
+            try {
+                comp = (Component)transfer.getTransferData(dfs[0]);
+            } catch (Throwable e) {
+                e.printStackTrace();
+                dtc.dropComplete(false);
+            }
+        }
+        dtc.dropComplete(true);
+
+        add(comp);
+    }
+
+    public boolean getResult() {
+        return passed;
+    }
+}
diff --git a/test/jdk/java/awt/dnd/ModalDialogDeadlockTest.java b/test/jdk/java/awt/dnd/ModalDialogDeadlockTest.java
new file mode 100644
index 00000000000..ca72ef8710f
--- /dev/null
+++ b/test/jdk/java/awt/dnd/ModalDialogDeadlockTest.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+import java.awt.Dialog;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.Transferable;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DragGestureEvent;
+import java.awt.dnd.DragGestureListener;
+import java.awt.dnd.DragGestureRecognizer;
+import java.awt.dnd.DragSource;
+import java.awt.dnd.DragSourceAdapter;
+import java.awt.dnd.DragSourceDropEvent;
+import java.awt.dnd.DragSourceListener;
+import java.awt.dnd.DropTarget;
+import java.awt.dnd.DropTargetAdapter;
+import java.awt.dnd.DropTargetDropEvent;
+import java.awt.dnd.DropTargetListener;
+import java.awt.event.AWTEventListener;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseEvent;
+
+/*
+  @test
+  @bug 4633417
+  @summary tests that drag operation doesn't cause hang when a modal dialog is
+           shown
+  @key headful
+  @run main ModalDialogDeadlockTest
+*/
+
+public class ModalDialogDeadlockTest implements AWTEventListener {
+
+    volatile Frame frame;
+    volatile Dialog dialog;
+    volatile Point dstPoint;
+    volatile Point srcPoint;
+    volatile Dimension d;
+
+    volatile DragSource dragSource;
+    volatile Transferable transferable;
+    volatile DragSourceListener dsl;
+    volatile DragGestureListener dgl;
+    volatile DragGestureRecognizer dgr;
+    volatile DropTarget dt;
+
+    static final Object SYNC_LOCK = new Object();
+    static final int FRAME_ACTIVATION_TIMEOUT = 2000;
+    static final int MOUSE_RELEASE_TIMEOUT = 1000;
+
+    Component clickedComponent = null;
+
+    public static void main(String[] args) throws Exception {
+        ModalDialogDeadlockTest test = new ModalDialogDeadlockTest();
+        EventQueue.invokeAndWait(test::init);
+        try {
+            test.start();
+        } finally {
+            EventQueue.invokeAndWait(() -> {
+                if (test.frame != null) {
+                    test.frame.dispose();
+                }
+            });
+        }
+    }
+
+    public void init() {
+        frame = new Frame("ModalDialogDeadlockTest");
+        frame.setBounds(100, 100, 200, 200);
+        dialog = new Dialog(frame, "Dialog", true);
+        dialog.setBounds(350, 100, 200, 200);
+
+        dragSource = DragSource.getDefaultDragSource();
+        transferable = new StringSelection("TEXT");
+        dsl = new DragSourceAdapter() {
+            public void dragDropEnd(DragSourceDropEvent dsde) {
+                synchronized (SYNC_LOCK) {
+                    SYNC_LOCK.notifyAll();
+                }
+            }
+        };
+        dgl = new DragGestureListener() {
+            public void dragGestureRecognized(DragGestureEvent dge) {
+                dge.startDrag(null, transferable, dsl);
+            }
+        };
+        dgr = dragSource.createDefaultDragGestureRecognizer(dialog,
+                        DnDConstants.ACTION_COPY,
+                        dgl);
+        final DropTargetListener dtl = new DropTargetAdapter() {
+            public void drop(DropTargetDropEvent dtde) {
+                dtde.rejectDrop();
+                dialog.dispose();
+            }
+        };
+        dt = new DropTarget(frame, dtl);
+
+        frame.getToolkit().addAWTEventListener(this, AWTEvent.MOUSE_EVENT_MASK);
+        frame.setVisible(true);
+    }
+
+    public static int sign(int n) {
+        return n < 0 ? -1 : n == 0 ? 0 : 1;
+    }
+
+    public void start() throws Exception {
+        final Robot robot = new Robot();
+
+        robot.delay(FRAME_ACTIVATION_TIMEOUT);
+
+        EventQueue.invokeAndWait(() -> {
+            dstPoint = frame.getLocationOnScreen();
+            d = frame.getSize();
+        });
+        dstPoint.translate(d.width / 2, d.height / 2);
+
+        if (!pointInComponent(robot, dstPoint, frame)) {
+            System.err.println("WARNING: Couldn't locate frame.");
+            return;
+        }
+
+        EventQueue.invokeLater(() -> {
+            dialog.setVisible(true);
+        });
+
+        robot.delay(FRAME_ACTIVATION_TIMEOUT);
+
+        EventQueue.invokeAndWait(() -> {
+            srcPoint = dialog.getLocationOnScreen();
+            d = dialog.getSize();
+        });
+        srcPoint.translate(d.width / 2, d.height / 2);
+
+        if (!pointInComponent(robot, srcPoint, dialog)) {
+            System.err.println("WARNING: Couldn't locate dialog.");
+            return;
+        }
+
+        robot.mouseMove(srcPoint.x, srcPoint.y);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        for (;!srcPoint.equals(dstPoint);
+             srcPoint.translate(sign(dstPoint.x - srcPoint.x),
+                                sign(dstPoint.y - srcPoint.y))) {
+            robot.mouseMove(srcPoint.x, srcPoint.y);
+            robot.delay(50);
+        }
+        synchronized (SYNC_LOCK) {
+            robot.mouseRelease(InputEvent.BUTTON1_MASK);
+            SYNC_LOCK.wait();
+        }
+    }
+
+    public void reset() {
+        clickedComponent = null;
+    }
+
+    public void eventDispatched(AWTEvent e) {
+        if (e.getID() == MouseEvent.MOUSE_RELEASED) {
+            clickedComponent = (Component)e.getSource();
+            synchronized (SYNC_LOCK) {
+                SYNC_LOCK.notifyAll();
+            }
+        }
+    }
+
+    boolean pointInComponent(Robot robot, Point p, Component comp)
+      throws InterruptedException {
+        robot.waitForIdle();
+        reset();
+        robot.mouseMove(p.x, p.y);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        synchronized (SYNC_LOCK) {
+            robot.mouseRelease(InputEvent.BUTTON1_MASK);
+            SYNC_LOCK.wait(MOUSE_RELEASE_TIMEOUT);
+        }
+
+        Component c = clickedComponent;
+
+        while (c != null && c != comp) {
+            c = c.getParent();
+        }
+
+        return c == comp;
+    }
+}
diff --git a/test/jdk/java/awt/dnd/ModalDialogOnDragDeadlockTest.java b/test/jdk/java/awt/dnd/ModalDialogOnDragDeadlockTest.java
new file mode 100644
index 00000000000..3730aec27c9
--- /dev/null
+++ b/test/jdk/java/awt/dnd/ModalDialogOnDragDeadlockTest.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+import java.awt.Dialog;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.Transferable;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DragGestureEvent;
+import java.awt.dnd.DragGestureListener;
+import java.awt.dnd.DragGestureRecognizer;
+import java.awt.dnd.DragSource;
+import java.awt.dnd.DropTarget;
+import java.awt.dnd.DropTargetAdapter;
+import java.awt.dnd.DropTargetDragEvent;
+import java.awt.dnd.DropTargetDropEvent;
+import java.awt.dnd.DropTargetListener;
+import java.awt.event.AWTEventListener;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseEvent;
+
+/*
+  @test
+  @bug 4352221
+  @summary verifies that showing a modal dialog on drag doesn't hang
+  @key headful
+  @run main ModalDialogOnDragDeadlockTest
+*/
+
+public class ModalDialogOnDragDeadlockTest implements AWTEventListener {
+
+    volatile Frame frame;
+    volatile Dialog dialog;
+    volatile Point srcPoint;
+    volatile Dimension d;
+    volatile boolean finished;
+
+    static final Object SYNC_LOCK = new Object();
+    static final int FRAME_ACTIVATION_TIMEOUT = 3000;
+    static final int DROP_COMPLETION_TIMEOUT = 5000;
+    static final int MOUSE_RELEASE_TIMEOUT = 1000;
+
+    volatile DragSource dragSource;
+    volatile Transferable transferable;
+    volatile DragGestureListener dragGestureListener;
+    volatile DragGestureRecognizer dragGestureRecognizer;
+    volatile DropTargetListener dropTargetListener;
+    volatile DropTarget dropTarget;
+
+    Component clickedComponent = null;
+
+    public static void main(String[] args) throws Exception {
+        ModalDialogOnDragDeadlockTest test = new ModalDialogOnDragDeadlockTest();
+        EventQueue.invokeAndWait(test::init);
+        try {
+            test.start();
+        } finally {
+            EventQueue.invokeAndWait(() -> {
+                if (test.frame != null) {
+                    test.frame.dispose();
+                }
+            });
+        }
+    }
+
+    public void init() {
+        frame = new Frame("ModalDialogOnDragDeadlockTest");
+        dialog = new Dialog(frame, "Modal dialog", true);
+        frame.setTitle("Test frame");
+        frame.setBounds(100, 100, 200, 200);
+
+        dragSource = DragSource.getDefaultDragSource();
+        transferable = new StringSelection("TEXT");
+        dragGestureListener = new DragGestureListener() {
+            public void dragGestureRecognized(DragGestureEvent dge) {
+                dge.startDrag(null, transferable);
+            }
+        };
+        dragGestureRecognizer =
+                dragSource.createDefaultDragGestureRecognizer(frame, DnDConstants.ACTION_COPY,
+                        dragGestureListener);
+        dropTargetListener = new DropTargetAdapter() {
+            public void dragOver(DropTargetDragEvent dtde) {
+                dialog.setBounds(200, 200, 200, 200);
+                dialog.setVisible(true);
+            }
+            public void drop(DropTargetDropEvent dtde) {
+                dtde.acceptDrop(DnDConstants.ACTION_COPY);
+                dtde.dropComplete(true);
+            }
+        };
+        dropTarget = new DropTarget(frame, dropTargetListener);
+
+        frame.getToolkit().addAWTEventListener(this, AWTEvent.MOUSE_EVENT_MASK);
+        frame.setVisible(true);
+    }
+
+    public static int sign(int n) {
+        return n < 0 ? -1 : n == 0 ? 0 : 1;
+    }
+
+    public void start() throws Exception {
+        finished = false;
+        Robot robot = new Robot();
+        robot.waitForIdle();
+
+        Thread.sleep(FRAME_ACTIVATION_TIMEOUT);
+        EventQueue.invokeAndWait(() -> {
+            srcPoint = frame.getLocationOnScreen();
+            d = frame.getSize();
+        });
+        srcPoint.translate(d.width / 2, d.height / 2);
+
+        if (!pointInComponent(robot, srcPoint, frame)) {
+            System.err.println("WARNING: Couldn't locate source frame.");
+            return;
+        }
+
+        final Point dstPoint = new Point(srcPoint);
+        dstPoint.translate(d.width / 4, d.height / 4);
+
+        robot.mouseMove(srcPoint.x, srcPoint.y);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        for (;!srcPoint.equals(dstPoint);
+             srcPoint.translate(sign(dstPoint.x - srcPoint.x),
+                                sign(dstPoint.y - srcPoint.y))) {
+            robot.mouseMove(srcPoint.x, srcPoint.y);
+            Thread.sleep(50);
+        }
+
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+
+        Thread.sleep(DROP_COMPLETION_TIMEOUT);
+    }
+
+    public void reset() {
+        clickedComponent = null;
+    }
+
+    public void eventDispatched(AWTEvent e) {
+        if (e.getID() == MouseEvent.MOUSE_RELEASED) {
+            clickedComponent = (Component)e.getSource();
+            synchronized (SYNC_LOCK) {
+                SYNC_LOCK.notifyAll();
+            }
+        }
+    }
+
+    boolean pointInComponent(Robot robot, Point p, Component comp)
+      throws InterruptedException {
+        robot.waitForIdle();
+        reset();
+        robot.mouseMove(p.x, p.y);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        synchronized (SYNC_LOCK) {
+            robot.mouseRelease(InputEvent.BUTTON1_MASK);
+            SYNC_LOCK.wait(MOUSE_RELEASE_TIMEOUT);
+        }
+
+        Component c = clickedComponent;
+
+        while (c != null && c != comp) {
+            c = c.getParent();
+        }
+
+        return c == comp;
+    }
+}
\ No newline at end of file
diff --git a/test/jdk/java/awt/dnd/ModalDialogOnDropDeadlockTest.java b/test/jdk/java/awt/dnd/ModalDialogOnDropDeadlockTest.java
new file mode 100644
index 00000000000..103cf9df12e
--- /dev/null
+++ b/test/jdk/java/awt/dnd/ModalDialogOnDropDeadlockTest.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+import java.awt.Dialog;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.Transferable;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DragGestureEvent;
+import java.awt.dnd.DragGestureListener;
+import java.awt.dnd.DragGestureRecognizer;
+import java.awt.dnd.DragSource;
+import java.awt.dnd.DragSourceAdapter;
+import java.awt.dnd.DragSourceDropEvent;
+import java.awt.dnd.DragSourceListener;
+import java.awt.dnd.DropTarget;
+import java.awt.dnd.DropTargetAdapter;
+import java.awt.dnd.DropTargetDropEvent;
+import java.awt.dnd.DropTargetListener;
+import java.awt.event.AWTEventListener;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+
+/*
+  @test
+  @bug 4623377
+  @summary verifies that showing a modal dialog on drop doesn't hang
+  @key headful
+  @run main ModalDialogOnDropDeadlockTest
+*/
+
+public class ModalDialogOnDropDeadlockTest implements AWTEventListener {
+
+    volatile Frame frame;
+    volatile Dialog dialog;
+    volatile Point srcPoint;
+    volatile Dimension d;
+    volatile boolean finished = false;
+
+    static final Object SYNC_LOCK = new Object();
+    static final int FRAME_ACTIVATION_TIMEOUT = 3000;
+    static final int DROP_COMPLETION_TIMEOUT = 5000;
+    static final int MOUSE_RELEASE_TIMEOUT = 1000;
+
+    volatile MouseListener mouseListener;
+
+    volatile Runnable dialogLocator;
+    volatile DragSourceListener dragSourceListener;
+    volatile DragSource dragSource;
+    volatile Transferable transferable;
+    volatile DragGestureListener dragGestureListener;
+    volatile DragGestureRecognizer dragGestureRecognizer;
+    volatile DropTargetListener dropTargetListener;
+    volatile DropTarget dropTarget;
+
+    Component clickedComponent = null;
+
+    public static void main(String[] args) throws Exception {
+        ModalDialogOnDropDeadlockTest test = new ModalDialogOnDropDeadlockTest();
+        EventQueue.invokeAndWait(test::init);
+        try {
+            test.start();
+        } finally {
+            EventQueue.invokeAndWait(() -> {
+                if (test.frame != null) {
+                    test.frame.dispose();
+                }
+            });
+        }
+    }
+
+    public void init() {
+        frame = new Frame();
+        dialog = new Dialog(frame, "Modal dialog", true);
+        frame.setTitle("ModalDialogOnDropDeadlockTest");
+        frame.setBounds(100, 100, 200, 200);
+
+        mouseListener = new MouseAdapter() {
+            public void mouseClicked(MouseEvent e) {
+                dialog.dispose();
+            }
+        };
+        dialogLocator = new Runnable() {
+            public void run() {
+                try {
+                    final Robot robot = new Robot();
+
+                    Thread.sleep(FRAME_ACTIVATION_TIMEOUT);
+
+                    final Point srcPoint = dialog.getLocationOnScreen();
+                    Dimension d = dialog.getSize();
+                    srcPoint.translate(d.width / 2, d.height / 2);
+                    robot.mouseMove(srcPoint.x, srcPoint.y);
+                    robot.mousePress(InputEvent.BUTTON1_MASK);
+                    robot.mouseRelease(InputEvent.BUTTON1_MASK);
+
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    dialog.dispose();
+                }
+            }
+        };
+        dragSourceListener = new DragSourceAdapter() {
+            public void dragDropEnd(DragSourceDropEvent dsde) {
+                finished = true;
+            }
+        };
+        dragSource = DragSource.getDefaultDragSource();
+        transferable = new StringSelection("TEXT");
+        dragGestureListener = new DragGestureListener() {
+            public void dragGestureRecognized(DragGestureEvent dge) {
+                dge.startDrag(null, transferable, dragSourceListener);
+            }
+        };
+        dragGestureRecognizer =
+                dragSource.createDefaultDragGestureRecognizer(frame, DnDConstants.ACTION_COPY,
+                        dragGestureListener);
+        dropTargetListener = new DropTargetAdapter() {
+            public void drop(DropTargetDropEvent dtde) {
+                dtde.acceptDrop(DnDConstants.ACTION_COPY);
+                dialog.addMouseListener(mouseListener);
+                dialog.setBounds(200, 200, 200, 200);
+                new Thread(dialogLocator).start();
+                dialog.setVisible(true);
+                dtde.dropComplete(true);
+            }
+        };
+        dropTarget = new DropTarget(frame, dropTargetListener);
+
+        frame.getToolkit().addAWTEventListener(this, AWTEvent.MOUSE_EVENT_MASK);
+        frame.setVisible(true);
+    }
+
+    public static int sign(int n) {
+        return n < 0 ? -1 : n == 0 ? 0 : 1;
+    }
+
+    public void start() throws Exception {
+        Robot robot = new Robot();
+        robot.waitForIdle();
+
+        Thread.sleep(FRAME_ACTIVATION_TIMEOUT);
+
+        EventQueue.invokeAndWait(() -> {
+            srcPoint = frame.getLocationOnScreen();
+            d = frame.getSize();
+        });
+        srcPoint.translate(d.width / 2, d.height / 2);
+
+        if (!pointInComponent(robot, srcPoint, frame)) {
+            System.err.println("WARNING: Couldn't locate source frame.");
+            return;
+        }
+
+        final Point dstPoint = new Point(srcPoint);
+        dstPoint.translate(d.width / 4, d.height / 4);
+
+        robot.mouseMove(srcPoint.x, srcPoint.y);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        for (;!srcPoint.equals(dstPoint);
+             srcPoint.translate(sign(dstPoint.x - srcPoint.x),
+                                sign(dstPoint.y - srcPoint.y))) {
+            robot.mouseMove(srcPoint.x, srcPoint.y);
+            Thread.sleep(50);
+        }
+
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+
+        Thread.sleep(DROP_COMPLETION_TIMEOUT);
+
+        if (!finished) {
+            throw new RuntimeException("DnD not finished");
+        }
+    }
+
+    public void reset() {
+        clickedComponent = null;
+    }
+
+    public void eventDispatched(AWTEvent e) {
+        if (e.getID() == MouseEvent.MOUSE_RELEASED) {
+            clickedComponent = (Component)e.getSource();
+            synchronized (SYNC_LOCK) {
+                SYNC_LOCK.notifyAll();
+            }
+        }
+    }
+
+    boolean pointInComponent(Robot robot, Point p, Component comp)
+      throws InterruptedException {
+        robot.waitForIdle();
+        reset();
+        robot.mouseMove(p.x, p.y);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        synchronized (SYNC_LOCK) {
+            robot.mouseRelease(InputEvent.BUTTON1_MASK);
+            SYNC_LOCK.wait(MOUSE_RELEASE_TIMEOUT);
+        }
+
+        Component c = clickedComponent;
+
+        while (c != null && c != comp) {
+            c = c.getParent();
+        }
+
+        return c == comp;
+    }
+}