Desktop API не поддерживается на текущей платформе

Я столкнулся с этой ошибкой:

java.lang.UnsupportedOperationException: Desktop API не поддерживается на текущей платформе

Я бы открыл файл из моего приложения Java. Я использую этот метод:

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

Как я могу решить эту проблему?

Ответы

Ответ 1

В основном проблема заключается в том, что интеграция с Java Desktop не очень хорошо работает в Linux.

Он был разработан для работы с Windows; что-то работает на других системах, но никто действительно не заботился о том, чтобы добавить им надлежащую поддержку. Даже если вы установите необходимые "библиотеки гномов", результаты будут неудовлетворительными.

Я столкнулся с той же проблемой некоторое время назад и придумал класс ниже.

Цель достигается с помощью системных команд:

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

Если ни одно из них не работает, оно пытается выполнить реализацию, предоставляемую Java Desktop.
Потому что этот обычно терпит неудачу, он пытался в качестве последнего средства.


Класс DesktopApi

Этот класс предоставляет статические методы open, browse и edit.
Он протестирован для работы в Linux (Kde и Gnome), Windows и Mac.

Если вы используете его, пожалуйста, дайте мне кредит.

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;
        }
    }
}

Ответ 2

Я использую Ubuntu 12.04 LTS 64-бит с Oracle jdk1.6.0_45 и имел ту же проблему. Im работает gnome-classic как рабочий стол вместо Unity. Это то, что сработало для меня:

sudo apt-get install libgnome2-0

После установки этого пакета я перезапустил приложение Java Swing и Desktop.getDesktop().open(new File("myfile")); работал отлично.

Ответ 3

Класс Desktop не поддерживается во всех системах.

Из учебника Java Swing Интеграция с классом рабочего стола:

Используйте метод isDesktopSupported(), чтобы определить, доступен ли Desktop API. В операционной системе Solaris и на платформе Linux этот API зависит от библиотек Gnome. Если эти библиотеки недоступны, этот метод вернет false. После определения того, что поддерживается Desktop API, то есть isDesktopSupported() возвращает true, приложение может извлекать экземпляр Desktop с помощью статического метода getDesktop().

В любом случае было бы лучше предоставить альтернативный способ открыть файл, если поддержка Desktop не поддерживается.

Ответ 4

Поддержка различается между реализациями на разных JDK. Я встретил "UnsupportedOperationException", используя OpenJDK 1.7.0. Переход на Oracle JDK 1.7 работал.

В тех случаях, когда это возможно, вы можете переключать JDK или предлагать, чтобы ваши пользователи переключали JDK для включения определенной функции.