Desktop API is not supported on the current platform
Asked Answered
M

4

25

I have encountered this error:

java.lang.UnsupportedOperationException: Desktop API is not supported on the current platform

I would open a file from my java application. I use this method:

Desktop.getDesktop().open(new File(report.html"));

How can i solve this problem?

Matins answered 1/8, 2013 at 20:42 Comment(2)
which platform are you using?Interlard
check this question: #102825Interlard
A
57

Basically, the problem is that Java Desktop integration doesn't work well on Linux.

It was designed to work good with Windows; something works on other systems, but nobody really cared to add proper support for those. Even if you install the required 'gnome libraries', the results will be poor.

I've faced the very same problem a while ago, and came up with the class below.

The goal is achieved by using system-specific commands:

KDE:     kde-open
GNOME:   gnome-open
Any X-server system: xdg-open
MAC:     open
Windows: explorer

If none of those works, it tries the implementation provided by Java Desktop.
Because this one usually fails, it's tried as the last resort.


DesktopApi class

This class provides static methods open, browse and edit.
It is tested to work on Linux (Kde and Gnome), Windows and Mac.

If you use it, please give me credit.

package net.mightypork.rpack.utils;

import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;


public class DesktopApi {

    public static boolean browse(URI uri) {

        if (openSystemSpecific(uri.toString())) return true;

        if (browseDESKTOP(uri)) return true;

        return false;
    }


    public static boolean open(File file) {

        if (openSystemSpecific(file.getPath())) return true;

        if (openDESKTOP(file)) return true;

        return false;
    }


    public static boolean edit(File file) {

        // you can try something like
        // runCommand("gimp", "%s", file.getPath())
        // based on user preferences.

        if (openSystemSpecific(file.getPath())) return true;

        if (editDESKTOP(file)) return true;

        return false;
    }


    private static boolean openSystemSpecific(String what) {

        EnumOS os = getOs();

        if (os.isLinux()) {
            if (runCommand("kde-open", "%s", what)) return true;
            if (runCommand("gnome-open", "%s", what)) return true;
            if (runCommand("xdg-open", "%s", what)) return true;
        }

        if (os.isMac()) {
            if (runCommand("open", "%s", what)) return true;
        }

        if (os.isWindows()) {
            if (runCommand("explorer", "%s", what)) return true;
        }

        return false;
    }


    private static boolean browseDESKTOP(URI uri) {

        logOut("Trying to use Desktop.getDesktop().browse() with " + uri.toString());
        try {
            if (!Desktop.isDesktopSupported()) {
                logErr("Platform is not supported.");
                return false;
            }

            if (!Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
                logErr("BROWSE is not supported.");
                return false;
            }

            Desktop.getDesktop().browse(uri);

            return true;
        } catch (Throwable t) {
            logErr("Error using desktop browse.", t);
            return false;
        }
    }


    private static boolean openDESKTOP(File file) {

        logOut("Trying to use Desktop.getDesktop().open() with " + file.toString());
        try {
            if (!Desktop.isDesktopSupported()) {
                logErr("Platform is not supported.");
                return false;
            }

            if (!Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) {
                logErr("OPEN is not supported.");
                return false;
            }

            Desktop.getDesktop().open(file);

            return true;
        } catch (Throwable t) {
            logErr("Error using desktop open.", t);
            return false;
        }
    }


    private static boolean editDESKTOP(File file) {

        logOut("Trying to use Desktop.getDesktop().edit() with " + file);
        try {
            if (!Desktop.isDesktopSupported()) {
                logErr("Platform is not supported.");
                return false;
            }

            if (!Desktop.getDesktop().isSupported(Desktop.Action.EDIT)) {
                logErr("EDIT is not supported.");
                return false;
            }

            Desktop.getDesktop().edit(file);

            return true;
        } catch (Throwable t) {
            logErr("Error using desktop edit.", t);
            return false;
        }
    }


    private static boolean runCommand(String command, String args, String file) {

        logOut("Trying to exec:\n   cmd = " + command + "\n   args = " + args + "\n   %s = " + file);

        String[] parts = prepareCommand(command, args, file);

        try {
            Process p = Runtime.getRuntime().exec(parts);
            if (p == null) return false;

            try {
                int retval = p.exitValue();
                if (retval == 0) {
                    logErr("Process ended immediately.");
                    return false;
                } else {
                    logErr("Process crashed.");
                    return false;
                }
            } catch (IllegalThreadStateException itse) {
                logErr("Process is running.");
                return true;
            }
        } catch (IOException e) {
            logErr("Error running command.", e);
            return false;
        }
    }


    private static String[] prepareCommand(String command, String args, String file) {

        List<String> parts = new ArrayList<String>();
        parts.add(command);

        if (args != null) {
            for (String s : args.split(" ")) {
                s = String.format(s, file); // put in the filename thing

                parts.add(s.trim());
            }
        }

        return parts.toArray(new String[parts.size()]);
    }

    private static void logErr(String msg, Throwable t) {
        System.err.println(msg);
        t.printStackTrace();
    }

    private static void logErr(String msg) {
        System.err.println(msg);
    }

    private static void logOut(String msg) {
        System.out.println(msg);
    }

    public static enum EnumOS {
        linux, macos, solaris, unknown, windows;

        public boolean isLinux() {

            return this == linux || this == solaris;
        }


        public boolean isMac() {

            return this == macos;
        }


        public boolean isWindows() {

            return this == windows;
        }
    }


    public static EnumOS getOs() {

        String s = System.getProperty("os.name").toLowerCase();

        if (s.contains("win")) {
            return EnumOS.windows;
        }

        if (s.contains("mac")) {
            return EnumOS.macos;
        }

        if (s.contains("solaris")) {
            return EnumOS.solaris;
        }

        if (s.contains("sunos")) {
            return EnumOS.solaris;
        }

        if (s.contains("linux")) {
            return EnumOS.linux;
        }

        if (s.contains("unix")) {
            return EnumOS.linux;
        } else {
            return EnumOS.unknown;
        }
    }
}
Agitato answered 1/8, 2013 at 20:53 Comment(7)
Altough installing libgnome2-0 fix it, we, as developers, have to workaround those things. Thank you! :-)Lifeline
@Agitato Good efforts. Keep it up. +1 for The goal is achieved by using system-specific commands.Jamieson
An improved version of MightyPork's class is available at github.com/jjYBdx4IL/github-utils/blob/master/src/main/java/com/…. Feel free to contribute improvements.Beestings
It was moved to github.com/jjYBdx4IL/misc/blob/master/swing-utils/src/main/java/…Arly
@Agitato have you considered wrapping this up as a library and distributing via bintray or similar? It'd be really useful for multiple projects to just be able to pull this in via a dependency. I'm happy to do so if you like, but since it's not my code I wouldn't want to without permission.Nonconcurrence
@MichaelBerry do you realize this post is six years old? I no longer even work with Java! Feel free to do whatever you want with itAgitato
@Agitato I did, but some of us poor sods still work with Java desktop apps ;) Thanks for that, I may package it up in due course.Nonconcurrence
B
16

I am using Ubuntu 12.04 LTS 64-bit with Oracle jdk1.6.0_45 and was having the same problem. I’m running gnome-classic as the desktop instead of Unity. This is what worked for me:

sudo apt-get install libgnome2-0

After installing this package I restarted my Java Swing app and Desktop.getDesktop().open(new File("myfile")); worked just fine.

Borrowing answered 5/11, 2013 at 18:17 Comment(1)
On CentOS 7 running XFCE, sudo yum install libgnome did the trick!Pickmeup
P
7

The Desktop class is not supported on all systems.

From the Java Swing tutorial How to Integrate with the Desktop Class:

Use the isDesktopSupported() method to determine whether the Desktop API is available. On the Solaris Operating System and the Linux platform, this API is dependent on Gnome libraries. If those libraries are unavailable, this method will return false. After determining that the Desktop API is supported, that is, the isDesktopSupported() returns true, the application can retrieve a Desktop instance using the static method getDesktop().

In any case, it would be best to provide an alternative way to open a file if there is no support for Desktop.

Plumber answered 1/8, 2013 at 20:57 Comment(0)
I
1

Support varies between implementations on the various JDKs. I encountered the "UnsupportedOperationException" using OpenJDK 1.7.0. Switching to the Oracle JDK 1.7 worked.

Where practical, you may be able to switch JDKs or suggest that your users switch JDKs to enable a certain feature.

Ildaile answered 21/10, 2013 at 0:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.