2016-03-28 95 views
2

JAVA 8u77上周发布(2016年3月23日)JAVA 8u77类加载器的bug - 寻找一个解决办法

嗨已经发布一个多月前一个相关的问题(关于JAVA 8u74) - 我现在发布的新问题,因为我们有更准确的信息,我的问题稍有不同。

随着我的Web Start应用程序,如果客户端安装更新,他将运行时出现错误:

java.security.cert.CertificateException: 
     Could not verify signing in resource: https://www.example.com:443/app/myFile.jar 
     at com.sun.deploy.security.TrustDecider.ensureAllJarEntriesSigned(Unknown Source) 
     …. 

潜水到代码中,我注意到了错误以下行制作:

ClassLoader classLoader = this.getClass().getClassLoader(); 
classLoader.getResource("").getPath(); 

第二行返回NULL。

此代码适用于JAVA 8u73及更早版本。 甲骨文证实了它是一个错误 - https://bugs.openjdk.java.net/browse/JDK-8152827

然而,我不知道我可以等待一个bug修复... 我们正在努力寻找一种解决方法......

这是我发现 -

我们试图用classloader访问的JAR文件不是应用程序类路径的一部分。 它们包含不属于JAVA代码的文件。

我们注意到,如果向JAR添加类文件,然后将JAR设置为项目和类路径的一部分,则错误不会重现。

但是我们的问题是我们有一个很长的动态JAR文件列表(我们定期创建新的JAR)。 每次应用程序加载时(使用JNLP文件) - 我们动态地将必要的JAR添加到JNLP文件列表中。 我们不可能为我们创建的每个新JAR进行应用程序的新部署。 (如上所述 - 这些JAR没有JAVA代码。)

当然,所有罐子都使用相同的可信证书进行签名。 而且 - 再次 - 在8u73上没有问题。

有没有人有解决办法的想法?

感谢

+0

我原以为解决方法是使用没有此bug的版本。我猜你无法控制使用哪个版本? –

+0

是 - 目前我要求客户不要安装更新。 – yos

+0

我认为甲骨文不知道如何解决这个问题,因为他们理解错误的可能比任何人都好。 –

回答

2

甲骨文大约有这里这个错误,https://bugs.openjdk.java.net/browse/JDK-8151624信息,但一般公众没有读访问该网址。 (我也没有,但是你链接的bug被标记为隐藏的bug的重复。)

所以我们没有办法做到这一点,Oracle没有任何有关它的信息,解决方法是使用8u73。

你必须手动卸载以前的JRE(http://java.com/newerversionexists将基于浏览器的操作系统您重定向到的指令),然后在这里下载8u73:http://www.oracle.com/technetwork/java/javase/downloads/java-archive-javase8-2177648.html#jre-8u73-oth-JPR

但是:你将不得不为Oracle帐户注册和给他们你的电子邮件地址,电话号码等,以便下载链接工作。

伟大的工作,甲骨文。

+0

感谢您的信息。 8u73确实有效。希望Oracle很快能够解决这个问题。 – Perneel

1

我在调用ClassLoader.getResource/getResourceAsStream时看到了这个问题,但在调用getResources时没有看到这个问题。因此,一种可能的解决方法可能是使用:

Thread.currentThread()。getContextClassLoader()。getResources(“some/path”)。

该路径应该是绝对的,但不能以'/'开头。 返回类型是URL的枚举。

0

我有一个完全相同的问题(堆栈跟踪问题)的应用程序。一切正在与8u73

With 8u74每次使用Java Control Panel时都会重现错误 - 临时文件设置 - “保留我的计算机上的临时文件”已选中。如果未选中,错误不会重现。

相同的行为适用于8u77。目前为止我发现的唯一差别是:如果首先取消选中“在我的电脑上保留临时文件”,然后再次检查,则错误无法每次重现。原因不明。

请注意,取消选中Java Control Panel中的此选项可能会降低应用程序的性能。尽管如此,取决于您的客户和应用程序,这可能是一个更好的解决方法,而不仅仅是要求不更新。

0

我们发现JRE 8u74-77中的这个异常是从另一个JAR加载资源引起的。所以this.getClass()不够好。另一个例子,对ResourceBundle.getBundle()的调用应该有第三个参数 - 来自资源所在JAR的类的加载器。还可以在JAR之间混洗资源文件。像SwingX这样的第三方库有更多的麻烦。
奇怪的是抛出的异常是CertificateException当更合适的时候会是“资源未找到”。

0

对我来说,解决方法是使用“version”标签声明jnlp档案文件中没有的依赖关系。

因此,举例来说,这种方式工作得很好:

<jar href="spring-aop-u15-2.5.5.jar"/> 

此解决方案有跟随着横向效应:

  • 版本下载协议不生效,所以每次用户执行应用程序,jws会向服务器询问应用程序中包含的每个jar。该jar不会被更新,但因为服务器可能会响应一个304表示它已经被更新,但是如果你的应用程序包含很多库,你将会有一些延迟启动应用程序,因为这将是每个库的一个http请求。
0

刚刚测试1.8u91并且该问题尚未解决,如前面的评论中所述。

0

黑暗的举动似乎。显然,Java SE Advanced上的客户可以立即利用错误修复,但非付费客户仍在等待包含错误修复的第一个GA版本。此外,公共JBS问题的整个事件标记为私人问题的重复,其状态无法看到。