<extension> 的陈旧 JNLP 文件(自 Java 9?)

Stale JNLP files for <extension> (since Java 9?)

我的 Java Web Start 应用程序的 JNLP 文件在 <resources> 中包含一个 <extension href="..."> 标记来引用第二个 JNLP 文件,它又引用公共资源。直到现在都没有问题(我认为)。

然而,对于 Java 9(内部版本 9.0.1+11),当启动 JNLP 文件时,无法加载第二个 JNLP 文件中引用的某些资源,因为它们不再存在。这是因为 Java Web Start 仍然有该 JNLP 的陈旧版本(在其缓存中)引用例如"foo-1.2.jar"(不再存在),而当前版本的 JNLP 引用 "foo-1.3.jar"。

这是 Java 9 错误还是我遗漏了什么?

更新 1: 由于这些公共(或共享)资源不经常更新,我现在不确定这个问题是否已经存在 Java 9.

更新 2: 再想一想,问题可能出在我没有在 jnlp 元素上指定 href。虽然在第一个 JNLP 中是故意的(因为在运行时插入了 application-desc 参数,这些参数会在重新加载时丢失),但在第二个 JNLP 中有点意外。


第一个 JNLP 看起来像这样(请注意扩展元素):

<?xml version='1.0' encoding='UTF-8' ?>
<jnlp
    spec="6.0+"
    codebase="https://example.com/158"
>
    ...
    <update check="timeout" policy="always"/>
    <resources>
        <java version="9.*" java-vm-args="-Xmx800m --add-opens=java.desktop/java.awt=ALL-UNNAMED --add-opens=java.desktop/sun.awt.dnd=ALL-UNNAMED --add-opens=java.desktop/sun.swing=ALL-UNNAMED" href="http://java.sun.com/products/autodl/j2se"/>
        <java version="1.8*" java-vm-args="-Xmx800m" href="http://java.sun.com/products/autodl/j2se"/>
        <jar href="foo-20171018-client.jar" main="true"/>
        <extension href="https://example.com/shared/shared.jnlp"/>
    </resources>
    <application-desc main-class="foo.bar.Baz"><argument>sessionKey</argument><argument>12</argument></application-desc>     
</jnlp>

第二个 JNLP 看起来像这样(引用 foo...jar):

<?xml version='1.0' encoding='UTF-8' ?>
<jnlp
    spec="6.0+"
    codebase="https://example.com/shared"
>
    ...
    <update check="timeout" policy="always"/>
    <resources>
        <java version="9.*" java-vm-args="-Xmx800m --add-opens=java.desktop/java.awt=ALL-UNNAMED --add-opens=java.desktop/sun.awt.dnd=ALL-UNNAMED --add-opens=java.desktop/sun.swing=ALL-UNNAMED" href="http://java.sun.com/products/autodl/j2se"/>
        <java version="1.8*" java-vm-args="-Xmx800m" href="http://java.sun.com/products/autodl/j2se"/>
        <jar href="foo-1.3.jar"/>
        <jar href="jhall-2.0.02.jar"/>
        <jar href="jmf-2.1.1.e.jar"/>
        <jar href="forms-1.2.jar"/>
    </resources>
    <component-desc/>
</jnlp>

来自JNLP specification - 6资源的下载和缓存:

6.5.3 Managing the Cache

The JNLP Client is responsible for managing the cache of downloaded resources. The JNLP Client must make sure that the following invariant is maintained:

Resources belonging to a particular application are never removed from the cache while the application is running.

此规则确保应用程序开发人员可以 关于资源在应用程序缓存中的假设 是 运行。特别是所有急切下载的资源 在整个过程中都将在缓存中本地可用 程序执行。

用于管理缓存的确切策略和算法是 依赖于实现。 一个合理的策略可能是首先清除 在标记为 eager 的资源之前输出标记为惰性的资源。

JNLP 客户端还可以以任何它认为合适的方式管理扩展。 它们可以随时卸载或保留 permanently. 如果调用扩展卸载程序,则另一个 请求扩展将需要重新下载它,并且 要重新运行的扩展安装程序。

我突出显示了可能适用于您的情况的相关部分。我认为这里发生的是,一旦您的扩展被下载到缓存中,它就永远不会根据 JNLP 扩展中的更改进行更新。

您可以做的是对 JNLP href 进行版本化,即从 https://example.com/shared/shared-1.0.jnlp 开始,如果内容发生变化(https://example.com/shared/shared-1.1.jnlp,...)则更新版本。

或者您可以使用扩展程序的 version 属性。

根据我目前的测试经验,Java9 几乎从未获得新的 JNLP。我必须清除缓存,如上所述,我们不能指望用户这样做。我看不出更改 HREF 是一种解决方案,因为这会破坏每个桌面 link。如果用户转到 HTML 页面并重新单击一个 ICON,我们将其更改为新的 HREF,则工作正常。但这不是解决方案。我目前正在考虑这是一个 Java 9 Java Web Start 错误,我希望他们尽快修复它。我会 post 一份错误报告,如果还没有的话。现在正在看。