Java Web Start始终在Windows XP上缓存JNLP文件

Nag*_*gyI 8 java distribution java-web-start

在我的公司,我们使用Java Web Start将客户端软件分发给客户.他们使用不同的Windows版本:XP,Vista和7.

我们在过去通过JWS部署了一个版本最少的版本.我们的最新版本包括几个文件更改,一些罐子不见了,其他的出现了,等等.

我们发现Windows XP计算机上的升级失败,因为JWS仍然试图查找在Web服务器上不再可用的jar文件.我已经检查了我的HTTP服务器日志,并且在应用程序启动期间永远不会从XP机器上访问JNLP文件.如果我在Vista或Windows 7上尝试相同的一切正常,JWS将获取JNLP描述符并在更新可用时下载差异.因此,在XP机器上,只有已知的jar文件才会更新,如果JWS没有从缓存的JNLP文件集中找到某些内容,则会抛出错误.

我编写了一个手动生成JNLP文件的servlet.我在我的servlet代码中使用以下头配置.

response.setDateHeader("Last-Modified", lastModification);
// IE won't download JNLP file if Cache-Control header presents
//response.setHeader("Cache-Control", "no-cache, must-revalidate");
response.setHeader("Expires", "Mon, 26 Jul 1990 05:00:00 GMT");
Run Code Online (Sandbox Code Playgroud)

这使得JNLP文件总是过时的,这应该在每次客户端通过JWS启动时触发重新检查文件.我甚至可以在XP上的缓存查看器中看到这个日期:

缓存查看器

我在Oracle的bugreport网站上发现了一个永远无法解决的问题:错误ID:6189106刚刚在Windows XP上对Java7进行了相同的测试,但这个问题仍然存在.但仅在XP上,因为部署缓存的路径中有空白字符("Documents and Settings").有人说,如果我将部署缓存的路径更改为没有空格字符的东西,它将解决问题.嗯,这不是一个真正的解决方案,因为用户几乎不能写到他们的个人资料以外的位置.

因为这个bug存在了这么长时间,我想应该有某种解决方法.我不想每次都告诉客户清除Java缓存并从Web重新安装应用程序.我们希望将来更快的发布周期,这将使其更加恶化.我希望有人对此有个好主意.:|

ale*_*aig 5

问题出在java webstart的cachedir的路径上.如果它包含空格(在XP中就是这种情况),则路径以错误的格式传递给javaws,这将阻止对jnlp文件的更新检查.

在deployment.properties文件中更改此路径,如下所示:

deployment.user.cachedir = C \:\ your\path - 此路径不应包含空格.

之前PS干净java缓存.

补充:问题似乎是在更新21之后出现的.


MB.*_*MB. 5

我想出了各种各样的hacky解决方案:

  1. 在JNLP文件中放置一个版本号,将其作为参数传递给main方法(例如<argument>1.0</argument>).或者,您可以传递显式时间戳.

  2. 检查a)java.versionjavawebstart.version系统属性,以查看您的应用是否在1.6.0_22和1​​.7.0_2(含)之间的任何内容上运行; b)检查deployment.user.cachedir系统属性以查看其中是否有空格.如果a)和b)都不是真的,那么继续执行下面的步骤可能没有意义,因为Java Web Start本应检查JNLP文件以进行更新.

  3. 在启动时,在显示任何表单之前,将您的JNLP文件下载到内存中(例如使用new URL(jnlpUrlString).openStream()等).我将JNLP文件的URL作为参数从JNLP文件本身传递到我的应用程序中,就像版本号一样.

  4. 检查JNLP文件以查看它是否包含传递给main方法的版本号(例如,简单的字符串搜索"<argument>" + versionNumberPassedIntoMainMethod + "</argument>").如果确实如此,那么你很好,因为你正在运行最新版本.如果没有,继续:

  5. 将JNLP文件保存在临时目录中(例如,使用File.createTempFile(...)).

  6. 让系统从临时目录中打开JNLP文件,例如,java.awt.Desktop.getDesktop().open(jnlpFile)如果您的目标是Java 1.6+.

  7. System.exit(0) 关闭应用程序的过时版本,让更新后的版本接管.

我还存储并检查注册表中的最后下载日期(使用java.util.prefs.Preferences),以防止多次下载或短时间重新打开.我的想法是减少我的代码中的错误的机会导致一些非常令人讨厌的事情,如无限循环的open-check-reopen-check-reopen-check等.我下载JNLP文件时超时,所以连接速度慢' t防止应用程序打开太久.但这些只是可选的额外内容.

随着我的应用运行<security><all-permissions/><security/>,下载JNLP文件,将其保存到计算机,并使用默认程序打开它没有任何问题.有可能使用javax.jnlp库找到每个步骤的变通方法,因此您不需要所有权限,但我不太确定.

总的来说,这种方法似乎运作良好.但是我仍然希望有一天像这样的Java Web Start漏洞已成为过去,因为这种hacky废话真的不应该是必要的.