What is the best way to detect whether an application is launched by Webstart

此生再无相见时 提交于 2019-12-03 17:31:21

问题


As it was made clear in my recent question, Swing applications need to explicitly call System.exit() when they are ran using the Sun Webstart launcher (at least as of Java SE 6).

I want to restrict this hack as much as possible and I am looking for a reliable way to detect whether the application is running under Webstart. Right now I am checking that the value of the system property "webstart.version" is not null, but I couldn't find any guarantees in the documentation that this property should be set by future versions/alternative implementations.

Are there any better ways (preferably ones that do not ceate a dependency on the the webstart API?)


回答1:


When your code is launched via javaws, javaws.jar is loaded and the JNLP API classes that you don't want to depend on are available. Instead of testing for a system property that is not guaranteed to exist, you could instead see if a JNLP API class exists:

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

This also avoids needing to include javaws.jar on your class path when compiling.

Alternatively you could switch to compiling with javaws.jar and catching NoClassDefFoundError instead:

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

Using ServiceManager.lookup(String) and UnavailableServiceException is trouble because both are part of the JNLP API. The ServiceManager.getServiceNames() is not documented to throw. We are specifically calling this code to check for a NoClassDefFoundError.




回答2:


Use the javax.jnlp.ServiceManager to retrieve a webstart service. If it is availabe, you are running under Webstart.

See http://download.java.net/jdk7/docs/jre/api/javaws/jnlp/index.html




回答3:


As you mentioned, checking the System property as follows is probably the cleanest way:

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

In a production system I have used the above technique for years.

You can also try to check to see if there are any properties that start with "jnlpx." but none of those are really "guaranteed" to be there either as far as I know.

An alternative could be to attempt to instantiate the DownloadService us suggested by Tom:

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

Of course that does have the downside of coupling your code to that API.




回答4:


I have no real experience with Java web start other than looking at it a few years back.

How about start your application with a parameter that you define than you set when the app is started via Java web start.

If you want to pass in arguments to your app, you have to add them to the start-up file (aka JNLP descriptor) using or elements.

Then check to see if these properties are set.

Again this is a suggestion I have not coded for JWS and it may not be this easy.




回答5:


You can check whether the current classloader is an instance of com.sun.jnlp.JNLPClassLoader (Java plugin 1) or sun.plugin2.applet.JNLP2ClassLoader (Java plugin 2). Despite the "applet" package, an applet using JNLP with the Java plugin 2 uses another classloader, sun.plugin2.applet.Applet2ClassLoader. It works with OpenJDK too.



来源:https://stackoverflow.com/questions/216315/what-is-the-best-way-to-detect-whether-an-application-is-launched-by-webstart

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!