Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrong class invoked in Multi-release JAR file on Java 9?

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 (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 installed.

Here are the contents of 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() { }
}

Finally, 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="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>

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

New update: When I use appletviewer on the html file (after taking out the "%" from width and height), the proper Java 9 class is invoked.

Another new update: A co-worker converted the Applet to use a JNLP file locally on the client, and the wrong java class was invoked. But when she changed the codebase field in the local JNLP file to point to the remote server, the resources were downloaded from the server and the proper Java 9 class was invoked.

Can anyone help me with this issue? How I could better troubleshoot the problem? I could post the Java console output for the "working cases" and the "failing cases" if that would help. I have requested a bug report to be created here: http://bugreport.java.com.
I was given an automatic internal review ID : 9051408

New update: Oracle can now reproduce the problem and have created this issue: https://bugs.openjdk.java.net/browse/JDK-8191541

And here are the Java 9 and pre-Java 9 implementations of VersionDependent:

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"; 
  } 
}
like image 884
Larry C. Avatar asked Oct 23 '17 17:10

Larry C.


People also ask

Is Multi Launch jar introduced in Java 9?

Multi-release JARs, aka MRJARs, are a new feature of the Java platform, included in the Java 9 JDK.

Can you create a multi-Release jar for different version of Java?

One of the new features that Java 9 brings us is the capability to build Multi-Release JARs (MRJAR). As the JDK Enhancement Proposal says, this allows us to have different Java release-specific versions of a class in the same JAR.

What is a multirelease jar?

A multi-release JAR file allows for a single JAR file to support multiple major versions of Java platform releases. For example, a multi-release JAR file can depend on both the Java 8 and Java 9 major platform releases, where some class files depend on APIs in Java 8 and other class files depend on APIs in Java 9.


1 Answers

Oracle can now reproduce the problem under JDK 9/9.0.1 and have created this issue under #JDK-8191541 where it can be tracked for the current updates.

Update: JDK-8191541 has been marked as a duplicate of #JDK-8192748 and will be fixed in JDK10 (scheduled to be released in March, 2018).

I have asked Oracle if they plan on back porting the fix to JDK9.

Update 1/29/2018: Oracle reported that they will NOT be back porting the fix to JDK9.

Update: 1/29/2018: Oracle pointed me to an early release of JDK 10, which is supposed to have the fix: http://jdk.java.net/10/ Unfortunately, when I tried the same Multi-release JAR test with Java JDK 10 EA, the problem remains. I am creating another bug entry, this time against JDK 10 EA.

I will post another update if/when there is a solution or a workaround.

like image 52
Larry C. Avatar answered Sep 22 '22 12:09

Larry C.