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

发布于 2024-07-07 04:26:23 字数 402 浏览 7 评论 0原文

正如我的最近的问题< /a>,Swing 应用程序在使用 Sun Webstart 启动器运行时需要显式调用 System.exit()(至少从 Java SE 6 开始)。

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

有没有更好的方法(最好是不依赖 webstart API 的方法?)

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?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

小伙你站住 2024-07-14 04:26:24

当您的代码通过 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。

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.

淡笑忘祈一世凡恋 2024-07-14 04:26:24

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

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

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

南烟 2024-07-14 04:26:24

正如您所提到的,按如下方式检查系统属性可能是最干净的方法:

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 的缺点。

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.

东走西顾 2024-07-14 04:26:24

除了几年前看过之外,我对 Java Web Start 没有任何实际经验。

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

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

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

同样,这是一个我没有为 JWS 编写的建议,而且可能没那么容易。

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.

赏烟花じ飞满天 2024-07-14 04:26:24

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文