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

孤者浪人 提交于 2019-12-03 05:46:34

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.

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

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.

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.

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.

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