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

Drag and Drop on Linux with KDE fails because of url-encoded filename

XMLWordPrintable

    • x86_64
    • linux

      ADDITIONAL SYSTEM INFORMATION :
      Linux; KDE Plasma Version 6.1.3, Wayland

      A DESCRIPTION OF THE PROBLEM :
      When you run attached code and try to drag and drop a file whose filename contains '[', URISyntaxException exception is thrown. This is due to the fact that KDE provides the filename with url-encoding which is invalid when constructing an URL class. An example of file path that causes the exception: /home/michal/].txt.

      There are many other characters that causes the exception I mentioned. [ is one of them.

      The solution to the problem seems to be very easy. Every filename should be url-decoded. JDK provides a utility method for that: java.net.URLDecoder.decode(String s, String enc).

      This bug is present in JDK 21 and in openjdk 24-ea 2025-03-18.

      I would be delighted if I could write fix for this bug.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the provided code and try to drag and drop a file whose filename contains [ character.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Drag and Drop of a file whose name contains the [ character does not cause an exception. An application is able to get a drag-and-dropped filename correctly.
      ACTUAL -
      java.awt.dnd.InvalidDnDOperationException: java.net.URISyntaxException: Illegal character in path at index 20: file:///home/michal/].txt
      at java.desktop/sun.awt.dnd.SunDropTargetContextPeer.getTransferData(SunDropTargetContextPeer.java:274)
      at java.desktop/sun.awt.datatransfer.TransferableProxy.getTransferData(TransferableProxy.java:73)
      at java.desktop/java.awt.dnd.DropTargetContext$TransferableProxy.getTransferData(DropTargetContext.java:387)
      at com.github.michal.SimpleDnD$1.drop(SimpleDnD.java:30)
      at java.desktop/sun.awt.dnd.SunDropTargetContextPeer.processDropMessage(SunDropTargetContextPeer.java:548)
      at java.desktop/sun.awt.X11.XDropTargetContextPeer.processDropMessage(XDropTargetContextPeer.java:185)
      at java.desktop/sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchDropEvent(SunDropTargetContextPeer.java:864)
      at java.desktop/sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchEvent(SunDropTargetContextPeer.java:788)
      at java.desktop/sun.awt.dnd.SunDropTargetEvent.dispatch(SunDropTargetEvent.java:48)
      at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4861)
      at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
      at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
      at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828)
      at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775)
      at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
      at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
      at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
      at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
      at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:98)
      at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:747)
      at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
      at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
      at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
      at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744)
      at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
      at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
      at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
      at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
      at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
      at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

      ---------- BEGIN SOURCE ----------
      import javax.swing.*;
      import java.awt.datatransfer.DataFlavor;
      import java.awt.dnd.DnDConstants;
      import java.awt.dnd.DropTarget;
      import java.awt.dnd.DropTargetDropEvent;
      import java.io.File;
      import java.util.List;

      public class SimpleDnD extends JFrame {

          public SimpleDnD() {

              setTitle("Drag & Drop Demo");

              setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              setLocationRelativeTo(null);

              setSize(500, 500);

              setVisible(true);

              setDropTarget(new DropTarget() {
                  @Override
                  public void drop(DropTargetDropEvent evt) {
                      try {
                          evt.acceptDrop(DnDConstants.ACTION_COPY);
                          List<File> droppedFiles = (List<File>)
                                  evt.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
                          evt.dropComplete(true);
                      } catch(Exception e) {
                          e.printStackTrace();
                      }
                  }
              });
          }

          public static void main(String[] args) {
              SwingUtilities.invokeLater(SimpleDnD::new);
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Change filename to avoid characters that causes problems.

      FREQUENCY : always


            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated: