正如我在最近的问题中明确指出的那样,Swing 应用程序在使用 Sun Webstart 启动器运行时需要显式调用 System.exit()(至少从 Java SE 6 开始)。
我想尽可能地限制这种黑客攻击,我正在寻找一种可靠的方法来检测应用程序是否在 Webstart 下运行。现在我正在检查系统属性“webstart.version”的值是否不为空,但我在文档中找不到任何保证该属性应该由未来版本/替代实现设置。
有没有更好的方法(最好是那些不依赖于 webstart API 的方法?)
正如我在最近的问题中明确指出的那样,Swing 应用程序在使用 Sun Webstart 启动器运行时需要显式调用 System.exit()(至少从 Java SE 6 开始)。
我想尽可能地限制这种黑客攻击,我正在寻找一种可靠的方法来检测应用程序是否在 Webstart 下运行。现在我正在检查系统属性“webstart.version”的值是否不为空,但我在文档中找不到任何保证该属性应该由未来版本/替代实现设置。
有没有更好的方法(最好是那些不依赖于 webstart API 的方法?)
当您的代码通过 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。
使用 javax.jnlp.ServiceManager 检索 webstart 服务。如果它可用,则您正在 Webstart 下运行。
见http://download.java.net/jdk7/docs/jre/api/javaws/jnlp/index.html
正如您所提到的,如下检查 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 的缺点。
除了几年前看它之外,我对 Java web start 没有真正的经验。
当应用程序通过 Java web start 启动时,如何使用您定义的参数启动您的应用程序。
如果您想将参数传递给您的应用程序,您必须使用或元素将它们添加到启动文件(也称为 JNLP 描述符)中。
然后检查是否设置了这些属性。
同样,这是一个我没有为 JWS 编码的建议,它可能并不容易。
您可以检查当前的类加载器是 com.sun.jnlp.JNLPClassLoader(Java 插件 1)还是 sun.plugin2.applet.JNLP2ClassLoader(Java 插件 2)的实例。尽管有“applet”包,使用 JNLP 和 Java 插件 2 的小程序使用另一个类加载器 sun.plugin2.applet.Applet2ClassLoader。它也适用于 OpenJDK。