Каков наилучший способ определить, запущено ли приложение Webstart
Как явствует из недавнего вопроса , приложениям Swing необходимо явно вызывать System.exit(), когда они запускаются с помощью запуска Sun Webstart (по крайней мере, с Java SE 6).
Я хочу как можно больше ограничить этот хак, и я ищу надежный способ определить, работает ли приложение под Webstart. Сейчас я проверяю, что значение системного свойства "webstart.version" не является нулевым, но я не мог найти никаких гарантий в документации, что это свойство должно быть установлено будущими версиями/альтернативными реализациями.
Есть ли какие-либо более эффективные способы (предпочтительно те, которые не зависят от API-интерфейса веб-сайта?)
Ответы
Ответ 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.
Ответ 2
Используйте javax.jnlp.ServiceManager для извлечения службы веб-центра.
Если он доступен, вы работаете под Webstart.
См. http://download.java.net/jdk7/docs/jre/api/javaws/jnlp/index.html
Ответ 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.