Search code examples
javaawtdeadlockgnomemanjaro

Is Desktop#browse supported on Linux platform just for Gnome desktop?


Running my Java application with this code:

if (Desktop.isDesktopSupported())
{
    Desktop d = Desktop.getDesktop();
    try
    {
        d.browse(new URI("someurl")); // someurl is just an example, I am opening real url
    }
    catch (IOException | URISyntaxException e)
    {
        logger.warn(ExceptionUtils.getStackTrace(e));
    }
}

results in application not responding (probably deadlock) on Manjaro Linux KDE. While it works with no problem on Windows, I do not want to check for OS in my application and allow it just for Windows. I have not tried other platforms yet.

What i use:

  • Adoptium JDK 11
  • Manjaro kernel 5.10.83-1-MANJARO 64bit
  • KDE Plasma 5.23.4
  • Qt 5.15.2

Detailed deadlock location:

Desktop class:

public void browse(URI uri) throws IOException {
        checkAWTPermission();
        checkExec();
        checkActionSupport(Action.BROWSE);
        Objects.requireNonNull(uri);
        peer.browse(uri); // <- goes here
    }

Deadlock happens in XDesktopPeer class that implements DesktopPeer interface (peer) on method gnome_url_show(...):

private void launch(URI uri) throws IOException {
        byte[] uriByteArray = ( uri.toString() + '\0' ).getBytes();
        boolean result = false;
        XToolkit.awtLock();
        try {
            if (!nativeLibraryLoaded) {
                throw new IOException("Failed to load native libraries.");
            }
            result = gnome_url_show(uriByteArray); // <- deadlock / app not responding here
        } finally {
            XToolkit.awtUnlock();
        }
        if (!result) {
            throw new IOException("Failed to show URI:" + uri);
        }
    }

So... is Desktop#browse supported on Linux platform just for Gnome desktop?

I am guessing this, because of that method name.

If yes, can I make a check for deadlock around my code, so I prevent this in my app? rather than checking for OS and distros?


Solution

  • There are already several questions on SO about that issue:

    There is also this discussion:

    https://bugs.launchpad.net/ubuntu/+source/openjdk-8/+bug/1574879

    where someone says:

    gnome_url_show is actually in libgnome-2-0 package

    So, if the package is missing, Desktop.browse() will fail. There are 2 solutions to fix that.

    Solution 1

    Install the libgnome package.

    Solution 2

    Execute xdg-open to open the URL, e.g.:

    Runtime.getRuntime().exec(new String[]{"xdg-open", someurl});