Есть ли безопасный, программный способ определить, безопасно ли открывать окно Swing? - PullRequest
4 голосов
/ 05 мая 2011

У меня есть Java-приложение, которое пользователь может вызвать из командной строки, запустив java -jar app.jar или из среды рабочего стола, дважды щелкнув файл .jar.

Я бы хотел, чтобы приложение могло определять, может ли оно безопасно запускать графический интерфейс Swing или использовать интерфейс командной строки. Если я просто начну вызывать функции Swing без проверки доступности оконной системы, Java выручит с InternalError.

Например, если я сбросил DISPLAY и запустил приложение, я получил:

java.lang.InternalError: Can't connect to X11 window server using '' as the value of the DISPLAY variable.
    at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
    at sun.awt.X11GraphicsEnvironment.access$200(X11GraphicsEnvironment.java:62)
    at sun.awt.X11GraphicsEnvironment$1.run(X11GraphicsEnvironment.java:178)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.awt.X11GraphicsEnvironment.(X11GraphicsEnvironment.java:142)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:186)
    at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:82)
    at sun.awt.X11.XToolkit.(XToolkit.java:112)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:186)
    at java.awt.Toolkit$2.run(Toolkit.java:849)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.awt.Toolkit.getDefaultToolkit(Toolkit.java:841)
        [etc]

Я мог бы просто попытаться ... перехватить InternalError и запустить интерфейс командной строки в этом случае, но я слышал, что нельзя отлавливать ошибки, потому что они могут оставить JVM в несовместимом состоянии. (Пожалуйста, поправьте меня, если я ошибаюсь.)

Можно ли как-нибудь проверить, смогу ли я безопасно открыть окно Swing, не перехватывая InternalError? (Я мог бы просто проверить, не является ли переменная среды DISPLAY не пустой, но непустой DISPLAY не является гарантией того, что X-сервер действительно работает. Этот подход также не будет работать в средах, отличных от X11.)

Ответы [ 2 ]

14 голосов
/ 05 мая 2011

Вы можете использовать GraphicsEnvironment.isHeadless()

4 голосов
/ 05 мая 2011

Я мог бы просто попытаться ... перехватить InternalError и запустить интерфейс командной строки в этом случае, но я слышал, что нельзя отлавливать ошибки, потому что они могут оставить JVM в несовместимом состоянии.(Пожалуйста, исправьте меня, если я ошибаюсь.)

Ваше понимание наполовину верно.

Плохая идея поймать ошибку и попытаться восстановить / продолжитьзапуск , поскольку JVM может (уже) находиться в состоянии, из которого восстановление невозможно.

Однако, обнаружение конкретной ошибки, вывод информативной диагностики на консоль и немедленный выход из JVM довольнобезопасная вещь, чтобы сделать.(Потоки System.out / err довольно устойчивы к большинству вещей, которые вызывают выброс Error.)

В этом конкретном случае, вероятно, вы ничего не можете сделать, чтобы восстановить.Так что спасение - это самый разумный вариант в любом случае.(Вызывать isHeadless() до того, как вы попытаетесь запустить графический интерфейс, лучше.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...