检测Webstart是否启动应用程序的最佳方法是什么?

时间:2008-10-19 11:47:34

标签: java java-web-start

正如我在recent question中明确指出的那样,Swing应用程序在使用Sun Webstart启动程序(至少从Java SE 6开始)运行时需要显式调用System.exit()。

我想尽可能地限制这个hack,我正在寻找一种可靠的方法来检测应用程序是否在Webstart下运行。现在我正在检查系统属性“webstart.version”的值是否为空,但我在文档中找不到任何保证,该属性应由未来版本/替代实现设置。

有没有更好的方法(最好不要停止对webstart API的依赖?)

5 个答案:

答案 0 :(得分:10)

当您的代码通过javaws启动时,将加载javaws.jar,并且您不想依赖的JNLP API类可用。您可以改为查看是否存在JNLP API类,而不是测试不保证存在的系统属性:

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。

答案 1 :(得分:5)

使用javax.jnlp.ServiceManager检索webstart服务。 如果可用,则在Webstart下运行。

请参阅http://download.java.net/jdk7/docs/jre/api/javaws/jnlp/index.html

答案 2 :(得分:4)

如前所述,按如下方式检查System属性可能是最简洁的方法:

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

在生产系统中,我多年来一直使用上述技术。

您还可以尝试检查是否有任何以“jnlpx”开头的属性。但据我所知,这些都没有真正“保证”在那里。

另一种方法是尝试实例化Tom建议的DownloadService:

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

当然,这确实存在将代码耦合到该API的缺点。

答案 3 :(得分:3)

除了几年前查看它之外,我没有Java web start的实际经验。

如何使用您定义的参数启动应用程序,而不是通过Java Web start启动应用程序时设置的参数。

如果要将参数传递给应用程序,则必须使用或元素将它们添加到启动文件(也称为JNLP描述符)中。

然后检查是否设置了这些属性。

这也是我没有为JWS编写的建议,可能不是那么容易。

答案 4 :(得分:0)

您可以检查当前的类加载器是否是com.sun.jnlp.JNLPClassLoader(Java插件1)或sun.plugin2.applet.JNLP2ClassLoader(Java插件2)的实例。尽管" applet"包,使用JNLP和Java插件2的applet使用另一个类加载器sun.plugin2.applet.Applet2ClassLoader。它也适用于OpenJDK。