Подтвердить что ты не робот

Каков наилучший способ определить, запущено ли приложение Webstart

Как явствует из недавнего вопроса , приложениям Swing необходимо явно вызывать System.exit(), когда они запускаются с помощью запуска Sun Webstart (по крайней мере, с Java SE 6).

Я хочу как можно больше ограничить этот хак, и я ищу надежный способ определить, работает ли приложение под Webstart. Сейчас я проверяю, что значение системного свойства "webstart.version" не является нулевым, но я не мог найти никаких гарантий в документации, что это свойство должно быть установлено будущими версиями/альтернативными реализациями.

Есть ли какие-либо более эффективные способы (предпочтительно те, которые не зависят от API-интерфейса веб-сайта?)

4b9b3361

Ответ 1

Когда ваш код запускается через javaws, загружается javaws.jar и доступны классы API JNLP, в которые вы не хотите зависеть. Вместо тестирования для системного свойства, которое не гарантируется, вы можете увидеть, существует ли класс API JNLP:

private boolean isRunningJavaWebStart() {
    boolean hasJNLP = false;
    try {
      Class.forName("javax.jnlp.ServiceManager");
      hasJNLP = true;
    } catch (ClassNotFoundException ex) {
      hasJNLP = false;
    }
    return hasJNLP;
}

Это также позволяет избежать необходимости включать javaws.jar в ваш путь к классу при компиляции.

В качестве альтернативы вы можете переключиться на компиляцию с помощью javaws.jar и вместо этого захватить NoClassDefFoundError:

private boolean isRunningJavaWebStart() {
    try {
        ServiceManager.getServiceNames();
        return ds != null;
    } catch (NoClassDefFoundError e) {
        return false;
    }
}

Использование ServiceManager.lookup(String) и UnavailableServiceException - проблема, потому что оба являются частью JNLP API. ServiceManager.getServiceNames() не задокументирован. Мы специально вызываем этот код для проверки NoClassDefFoundError.

Ответ 3

Как вы упомянули, проверка свойства System следующим образом - это, пожалуй, самый чистый способ:

private boolean isRunningJavaWebStart() {
    return System.getProperty("javawebstart.version", null) != null;
}

В производственной системе я использовал эту технику в течение многих лет.

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

Альтернативой может быть попытка создать экземпляр DownloadService, предложенный Томом:

private boolean isRunningJavaWebStart() {
    try {
        DownloadService ds = (DownloadService) ServiceManager.lookup("javax.jnlp.DownloadService");
        return ds != null;
    } catch (UnavailableServiceException e) {
        return false;
    }
}

Конечно, это имеет недостаток в сочетании вашего кода с этим API.

Ответ 4

У меня нет реального опыта работы с веб-сайтом Java, кроме как смотреть на него несколько лет назад.

Как насчет запуска приложения с параметром, который вы определяете, чем вы устанавливаете при запуске приложения через веб-запуск Java.

Если вы хотите передать аргументы вашему приложению, вы должны добавить их в файл запуска (как JNLP-дескриптор) с помощью или элементов.

Затем проверьте, установлены ли эти свойства.

Снова это предложение, которое я не кодировал для JWS, и это может быть не так просто.

Ответ 5

Вы можете проверить, является ли текущий загрузчик классов экземпляром com.sun.jnlp.JNLPClassLoader(Java-плагин 1) или sun.plugin2.applet.JNLP2ClassLoader (плагин Java 2). Несмотря на пакет "апплет", апплет, использующий JNLP с плагином Java 2, использует другой загрузчик классов, sun.plugin2.applet.Applet2ClassLoader. Он также работает с OpenJDK.