JAVA 8u77 classLoader bug - 寻找变通方法

时间:2016-03-28 08:10:31

标签: java jar classpath java-web-start

JAVA 8u77于上周(2016年3月23日)发布

你好一个月前发布了一个相关问题(关于JAVA 8u74) - 我现在发布一个新问题,因为我们有更准确的信息,我的问题略有不同。

使用我的网络启动应用程序,如果客户端安装了更新,他将在运行时遇到错误:

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及更早版本。 Oracle证实这是一个错误 - https://bugs.openjdk.java.net/browse/JDK-8152827

然而,我不确定我是否可以等待错误修复...... 我们正在努力寻找解决方法......

这是我发现的 -

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

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

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

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

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

由于

7 个答案:

答案 0 :(得分:2)

Oracle在此处提供了有关此错误的信息,https://bugs.openjdk.java.net/browse/JDK-8151624,但普通公众对该网址没有读取权限。 (我也没有,但是您链接的错误被标记为隐藏错误的副本。)

所以我们无能为力,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帐户并向他们提供您的电子邮件地址,电话号码等,以便下载链接正常工作。

干得好,甲骨文。

答案 1 :(得分:1)

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

Thread.currentThread()。getContextClassLoader()。getResources( “一些/路径”)。

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

答案 2 :(得分:0)

我的应用程序具有完全相同的问题(堆栈跟踪问题)。一切都与8u73一起使用。

使用8u74每次都可以使用Java Control Panel - 临时文件设置 - "将临时文件保存在我的计算机上"检查。如果未选中,则错误不会重现。

同样的行为适用于8u77。到目前为止我发现的差异:如果"将临时文件保存在我的电脑上"首先取消选中,然后再次检查,错误每次都不可重现。原因尚不清楚。

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

我的解决方法是使用"版本"声明jnlp存档中的依赖关系 ;标签

因此,例如,这种方式可以正常工作:

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

该解决方案具有以下横向效应:

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

答案 5 :(得分:0)

刚刚测试了1.8u91,问题尚未修复,如之前的评论所示。

答案 6 :(得分:0)

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