<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 一份错误报告,如果还没有的话。现在正在看。
我的 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 一份错误报告,如果还没有的话。现在正在看。