JDK-8191541 : Wrong class invoked in Multi-release JAR file on Java 9 when running using file protocol
  • Type: Bug
  • Component: deploy
  • Sub-Component: plugin
  • Affected Version: 9,10
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows_7
  • CPU: x86
  • Submitted: 2017-10-31
  • Updated: 2018-02-09
  • Resolved: 2018-01-30
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
C:\Program Files\EMC\Unisphere VNX Client>java -version
java version "9"
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) Server VM (build 9+181, mixed mode, emulated-client, sharing)


ADDITIONAL OS VERSION INFORMATION :
Windows 7, 32 bit, running Java 9 build 9+181

EXTRA RELEVANT SYSTEM CONFIGURATION :
Internet Explorer V11

A DESCRIPTION OF THE PROBLEM :
I am seeing a problem with an Applet using a multi-release JAR, which I hope someone can help me with.

I have a very simplified multi-release jar file with a class named VersionDependent. Its method "version" should display "Java 9 version" when running on a Java 9 JRE system, and display "Java 8 or earlier version" when running on a Java 8 JRE system.

When I run the Applet by entering this URL of the SERVER (http://10.nnn.nn.nn/testLAC.html) into my browser (Internet Explorer V11) on a client machine running Java JRE 9, everything works correctly; it displays "Java 9 version" as expected. 

But when I run the Applet by entering this URL (file:///C:/FOLDER_NAME/testLAC.html) on the same client machine to view the page locally, it unexpectedly displays "Java 8 or earlier version". It looks like the Java 9 specific VersionDependent class of the Multi-release Jar does not get invoked. Can someone help me understand why the multi-release JAR is not working as expected? The client machine only has Java JRE 9 181 installed.

When I run from the command line, the proper Java 9 class is invoked. 

When I use appletviewer on the html file, the proper Java 9 class is invoked. 

We converted the Applet to use a JNLP file locally on the client (codebase="."), and the wrong java class was invoked. But when we changed the codebase field in the local JNLP file to point to the remote server (codebase="http://10.xx.yy.zz"), the resources were downloaded from the server and the proper Java 9 class was invoked. 

Below, I have attached the contents of the multi-release JAR file, the source code, the HTML file and the JNLP file.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Created the multi-release mr.jar and my testAppletLAC.jar.
2. Signed the jar files.
3. Created the html file.
4. Loaded the jar files and html file onto the CLIENT machine.
5. Loaded the jar files on the SERVER machine too.
6. When I run the Applet by entering this URL (file:///C:/FOLDER_NAME/testLAC.html) on the same client machine to view the page locally, it unexpectedly displays "Java 8 or earlier version". It looks like the Java 9 specific VersionDependent class of the Multi-release Jar does not get invoked. 
7. When I run the Applet by entering this URL of the SERVER(http://10.nnn.nn.nn/testLAC.html) into my browser (Internet Explorer V11) on a client machine running Java JRE 9, everything works correctly; it displays "Java 9 version" as expected. 
8. I created the JNLP file, with codebase="."
9. When I run the applet via the JNLP file, the "Java 8 or earlier version" is displayed by mistake.
10. I changed the JNLP file so codebase="http://10.xx.yy.zz", the JAR files are downloaded from the SERVER, and the proper "Java 9 version" is displayed.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
"Java 9 version"
ACTUAL - 
 "Java 8 or earlier version"

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
The Multi-release JAR file:

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
------
Here is the test Applet code that displays the Java JRE's version and then calls into 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, 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",10,70);
    } else {
        String a = "VersionDependent.version is not null. Output: " + test;
        g.drawString(a,10,90);
    }

  }

  public void init() { }
}
--------
Here is the HTML file that uses the test Applet JAR and the multi-release JAR:

<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="900" height="300" 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>
------
Here is the JNLP file with codebase=".", which shows the wrong version:
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.5" codebase="." href="testAppletLAC.jnlp">
   <information>
      <title>Unisphere</title>
      <vendor>Qoppa Softwar LLC</vendor>
      <description>Unisphere</description>
      <description kind="short">Unisphere GUI</description>
      <offline-allowed/>
   </information>
   <security>
      <all-permissions/>
   </security>
   <resources>
<j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se" java-vm-args="-Djava.net.preferIPv4Stack=true -verbose:class --add-exports=java.desktop/com.sun.java.swing.plaf.windows=ALL-UNNAMED" max-heap-size="512m"/>
<jar href="testAppletLAC.jar" main="true"/>
<jar href="mr.jar" main="true"/>
   </resources>
   <applet-desc
      documentBase="." name="TestAppletLAC" main-class="appletExample.TestAppletLAC" width="1000" height="1000">
    <param name="codebase_lookup" value="false"/>
                <param name="START_BACKGROUND" value="65A0EA"/>
                <param name="END_BACKGROUND" value="2F63AC"/>
                <param name="java_arguments" value="-Djnlp.packEnabled=false -verbose:class"/>
  </applet-desc>
</jnlp>
---
And here is the JNLP with codebase pointing to the server.  The JAR files are downloaded and the proper "Java 9 version" is displayed.
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.5" codebase="http://10.xx.yy.zz" href="testAppletLAC.jnlp">
   <information>
      <title>Unisphere</title>
      <vendor>Qoppa Softwar LLC</vendor>
      <description>Unisphere</description>
      <description kind="short">Unisphere GUI</description>
      <offline-allowed/>
   </information>
   <security>
      <all-permissions/>
   </security>
   <resources>
<j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se" java-vm-args="-Djava.net.preferIPv4Stack=true -verbose:class --add-exports=java.desktop/com.sun.java.swing.plaf.windows=ALL-UNNAMED" max-heap-size="512m"/>
<jar href="testAppletLAC.jar" main="true"/>
<jar href="mr.jar" main="true"/>
   </resources>
   <applet-desc
      documentBase="." name="TestAppletLAC" main-class="appletExample.TestAppletLAC" width="1000" height="1000">
    <param name="codebase_lookup" value="false"/>
                <param name="START_BACKGROUND" value="65A0EA"/>
                <param name="END_BACKGROUND" value="2F63AC"/>
                <param name="java_arguments" value="-Djnlp.packEnabled=false -verbose:class"/>
  </applet-desc>
</jnlp>

---------- END SOURCE ----------


Comments
Also read: The deployment stack may be included in Java SE 9 or later releases, Java SE 8 is the recommended and only supported version of the deployment stack. http://www.oracle.com/technetwork/java/eol-135779.html https://blogs.oracle.com/java-platform-group/extension-of-oracle-java-se-8-public-updates-and-java-web-start-support
09-02-2018

Reopening this report based upon submitter confirmation that the fix in JDK 10 does not resolve the issue. Updating with detailed response from submitter: ==================================== 1. Was the fix to the Multi release jar file issue in JDK 10? Or in JRE 10? 2. https://bugs.openjdk.java.net/browse/JDK-8192748 says the fix was resolved in ���build b36���. Does that mean that the fix should be in the JDK 10 ea build at http://jdk.java.net/10/ (jdk-10-ea+38_windows-x64_bin.exe)? 3. I tried my test with jdk 10, ea 38, and I am still seeing the same problem. Note: Also attaching detailed steps to reproduce.
30-01-2018

Response from submitter ( With respect to what ?): ======================== Will programs compiled with JDK 9 (and earlier) be able to be run on JRE 10? ========================
03-01-2018

The final version of JDK9 - 9.0.4 is not expected contain this fix . "And finally, with JDK 10 be backwards compatible with previous releases? " With respect to what ?,
18-12-2017

Additional information from submitter: ���==================== Additional Information: I noticed that JDK-8191541 was marked as a duplicate of JDK-8192748, which is fixed by JDK-8132734 in JDK 10. Do you know if a new version of JDK 9 (ie, 9.0.2) will be released with the same fix? If so, do you know when? And finally, with JDK 10 be backwards compatible with previous releases? =========================
18-12-2017

I thought this was due to URL permissions granted to untrusted content, since we grant URL permission to the loaded jar when it is loaded from http or https, but no longer grant file permissions when loaded from file URL. However i made a signed all-permissions version of the test applet and got the same results. The applet loaded from http URL will use the version resource in the jar from version 9, and the same applet loaded from file URL will use the unversioned version of the resource.
29-11-2017

I can reproduce this with IE (Firefox ESR will not even try to run local applets.)
29-11-2017

simplified example using attached jars posted on web at: http://oklahoma.us.oracle.com/www/tests/multi/test.html works fine as expected. I have not been able to get anything to work yet using file protocol on windows - in progress.
27-11-2017

Reported with: JDK 9 GA Windows 7 (32 bit) According to description, an applet using a multi-release JAR when run locally unexpectedly displays "Java 8 or earlier version", whereas when run ona client machine through web server displays correct information "Java 9 JRE" The test case contains a multi-release jar file with a class named VersionDependent. Its method "version" should display "Java 9 version" when running on a Java 9 JRE system, and display "Java 8 or earlier version" when running on a Java 8 JRE system. Verified with: JDK 9/9.0.1 Windows 10 (64-bit) Could reproduce the results as explained. See attached screenshots for reference. Results: ================ JDK 9: FAIL JDK 9.0.1: FAIL To check, run the testLAC.html from the test case (subsequent comment) from a web server and then locally and see the difference. This issue is also being discussed at Stackverflow: https://stackoverflow.com/questions/46895475/wrong-class-invoked-in-multi-release-jar-file-on-java-9
20-11-2017