我有一个非常简化的多版本jar文件,其中有一个名为VersionDependent的类.它的方法“版本”应该显示
在Java 9 JRE系统上运行时的“Java 9版本”,并在Java 8 JRE系统上运行时显示“Java 8或更早版本”.
当我通过在运行Java JRE 9的客户端计算机上将此URL(http://10.nnn.nn.nn/testLAC.html)输入我的浏览器(Internet Explorer V11)来运行Applet时,一切正常;它按预期显示“Java 9版本”.
但是当我通过在同一客户端计算机上输入此URL(文件:/// C:/FOLDER_NAME/testLAC.html)来运行Applet以在本地查看页面时,它意外地显示“Java 8或更早版本”.看起来不会调用Multi-release Jar的Java 9特定VersionDependent类.有人可以帮助我理解为什么多版本JAR没有按预期工作?客户端计算机仅安装了Java JRE 9.
- jar tvf mr.jar | more
- 0 Mon Oct 23 08:52:38 EDT 2017 Meta-INF/
- 82 Mon Oct 23 08:52:38 EDT 2017 Meta-INF/MANIFEST.MF (This has Multi-Release: true !)
- 0 Thu Jun 08 07:58:28 EDT 2017 com/
- 0 Thu Jun 08 07:58:28 EDT 2017 com/emc/
- 0 Mon Oct 23 08:50:40 EDT 2017 com/emc/demo/
- 324 Mon Oct 23 08:43:44 EDT 2017 com/emc/demo/VersionDependent.class
- 0 Thu Jun 08 07:58:28 EDT 2017 Meta-INF/versions/9/
- 0 Thu Jun 08 07:58:28 EDT 2017 Meta-INF/versions/9/com/
- 0 Thu Jun 08 07:58:28 EDT 2017 Meta-INF/versions/9/com/emc/
- 0 Thu Jun 08 08:24:32 EDT 2017 Meta-INF/versions/9/com/emc/demo/
- 313 Mon Oct 23 08:47:34 EDT 2017 Meta-INF/versions/9/com/emc/demo/VersionDependent.class
下面是测试Applet代码,它显示Java JRE的版本,然后调用VersionDependent.version:
- package appletExample;
- //Reference the required Java libraries
- import java.applet.Applet;
- import java.awt.*;
- import com.emc.demo.VersionDependent;
- //The applet code
- public class TestAppletLAC extends Applet {
- private Button button1;
- public void paint(Graphics g) {
- // Draw a rectangle width=250,height=100
- g.drawRect(0,500,100);
- // Set the color to blue
- g.setColor(Color.blue);
- g.drawString("Major version: " + System.getProperty("java.version"),10,50);
- String test = new VersionDependent().version();
- if(test == null){
- g.drawString("VersionDependent.version is null",70);
- } else {
- String a = "VersionDependent.version is not null. Output: " + test;
- g.drawString(a,90);
- }
- }
- public void init() { }
- }
最后,这是使用测试Applet JAR和多版本JAR的HTML文件:
- <HTML>
- <HEAD>
- <TITLE></TITLE>
- <Meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <Meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
- </HEAD>
- <BODY topmargin="0" leftmargin="0" marginwidth="0" marginheight="0">
- <applet codebase="." mayscript="true" width="100%" height="100%" codebase_lookup="false" START_BACKGROUND="65A0EA" END_BACKGROUND="2F63AC" code="appletExample.TestAppletLAC" archive="mr.jar,testAppletLAC.jar" name="FxApplet">
- <param name="separate_jvm" value="true"/><param name="java_arguments" value="-Djnlp.packEnabled=false"/><param name="codebase_lookup" value="false"/>
- </applet>
- </HTML>
当我从命令行运行时,调用适当的Java 9类.
新更新:当我在html文件上使用appletviewer时(从宽度和高度取出“%”之后),调用适当的Java 9类.
另一个新的更新:一个同事将Applet转换为在客户端本地使用JNLP文件,并调用了错误的java类.但是,当她将本地JNLP文件中的codebase字段更改为指向远程服务器时,资源从服务器下载并调用了正确的Java 9类.
任何人都可以帮我解决这个问题吗?我怎样才能更好地排除问题?如果有帮助,我可以发布“工作案例”和“失败案例”的Java控制台输出.我已经要求在这里创建一个错误报告:http://bugreport.java.com.
我得到了一个自动内部审查ID:9051408
新更新:Oracle现在可以重现该问题并创建了此问题:
https://bugs.openjdk.java.net/browse/JDK-8191541
以下是VersionDependent的Java 9和Java 9之前的实现:
- package com.emc.demo;
- /**
- * This is the Java 9 version of the class `VersionDependent`.
- */
- public class VersionDependent {
- public String version() {
- return "Java 9 version";
- }
- }
- package com.emc.demo;
- /**
- * This is the pre Java 9 version of the class `VersionDependent`.
- */
- public class VersionDependent {
- public String version() {
- return "Java 8 or earlier version";
- }
- }
解决方法
更新:JDK-8191541已被标记为#JDK-8192748的副本,将在JDK10中修复(计划于2018年3月发布).
我问他们是否计划将修复程序移植到JDK9.
更新1/29/2018:Oracle报告他们不会将修复程序移植回JDK9.
更新:1/29/2018:Oracle向我指出JDK 10的早期版本,它应该有修复:
http://jdk.java.net/10/
不幸的是,当我使用Java JDK 10 EA尝试相同的多版本JAR测试时,问题仍然存在.我正在创建另一个错误条目,这次是针对JDK 10 EA.