JDK-8193522 : meta-index in 1.8.0_152 does not include jfxrt.jar entries
  • Type: Bug
  • Component: install
  • Sub-Component: install
  • Affected Version: 8u152
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86_64
  • Submitted: 2017-12-08
  • Updated: 2021-04-01
  • Resolved: 2018-02-01
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8u171 b05Fixed
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
Version for running 144

java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

Version for running 152
java version "1.8.0_152"
Java(TM) SE Runtime Environment (build 1.8.0_152-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.152-b16, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux whitefly 2.6.32-696.1.1.el6.x86_64 #1 SMP Tue Mar 21 12:19:18 EDT 2017 x86_64 x86_64 x86_64 GNU/Linux

EXTRA RELEVANT SYSTEM CONFIGURATION :
Scripts for running located in the TestApplication directory

Script for testing 144

#!/bin/bash

export JAVA_HOME=/usr/java/jdk1.8.0_144
export NETBEANS_HOME=/usr/local/netbeans-8.2
export ANT_HOME=${NETBEANS_HOME}/extide/ant
export JAVA=${JAVA_HOME}/bin
export NETBEANS=${NETBEANS_HOME}/bin
export ANT=${ANT_HOME}/bin
export PATH=${JAVA}:${NETBEANS}:${ANT}:${PATH}

uname -a
java -version
cd dist
java -classpath $(pwd)/TestApplication.jar -jar TestApplication.jar

Script for testing 152

#!/bin/bash

export JAVA_HOME=/usr/java/jdk1.8.0_152
export NETBEANS_HOME=/usr/local/netbeans-8.2
export ANT_HOME=${NETBEANS_HOME}/extide/ant
export JAVA=${JAVA_HOME}/bin
export NETBEANS=${NETBEANS_HOME}/bin
export ANT=${ANT_HOME}/bin
export PATH=${JAVA}:${NETBEANS}:${ANT}:${PATH}

uname -a
java -version
cd dist
java -classpath $(pwd)/TestApplication.jar -jar TestApplication.jar


A DESCRIPTION OF THE PROBLEM :
When getting the MANIFEST.MF for a class in an application jar I am getting jar:file:/usr/java/jdk1.8.0_152/jre/lib/ext/jfxrt.jar!/META-INF/MANIFEST.MF instead of getting jar:file:/users/sewardge/NetBeansProjects/TestApplication/dist/TestApplication.jar!/META-INF/MANIFEST.MF as expected.

By the way I believe the code works on 151.


REGRESSION.  Last worked in version 8u144

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.  Created a java application called TestApplication.
2.  Created a jframe form called TestWindow.
3.  Created a jpanel in the form.
4.  Created a jbutton in the jpanel.
5.  Added the following code to the post init of the button.
        URL manifestURL;
        manifestURL = getClass().getResource("/META-INF/MANIFEST.MF");
        System.out.println("class getResource manifestURL = " + manifestURL);
        manifestURL = TestWindow.class.getResource("/META-INF/MANIFEST.MF");
        System.out.println("class getResource manifestURL = " + manifestURL);
        manifestURL = ((URLClassLoader) TestWindow.class.getClassLoader()).getResource("META-INF/MANIFEST.MF");
        System.out.println("URLClassLoader getResource manifestURL = " + manifestURL);
        manifestURL = ((URLClassLoader) TestWindow.class.getClassLoader()).findResource("META-INF/MANIFEST.MF");
        System.out.println("URLClassLoader findResource manifestURL = " + manifestURL);
6. Fixed the imports.
7. Built the application using netbeans.
Ran the scripts mentioned in the additional configuration section.



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Linux whitefly 2.6.32-696.1.1.el6.x86_64 #1 SMP Tue Mar 21 12:19:18 EDT 2017 x86_64 x86_64 x86_64 GNU/Linux
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
class getResource manifestURL = jar:file:/users/sewardge/NetBeansProjects/TestApplication/dist/TestApplication.jar!/META-INF/MANIFEST.MF
class getResource manifestURL = jar:file:/users/sewardge/NetBeansProjects/TestApplication/dist/TestApplication.jar!/META-INF/MANIFEST.MF
URLClassLoader getResource manifestURL = jar:file:/users/sewardge/NetBeansProjects/TestApplication/dist/TestApplication.jar!/META-INF/MANIFEST.MF
URLClassLoader findResource manifestURL = jar:file:/users/sewardge/NetBeansProjects/TestApplication/dist/TestApplication.jar!/META-INF/MANIFEST.MF

ACTUAL -
Linux whitefly 2.6.32-696.1.1.el6.x86_64 #1 SMP Tue Mar 21 12:19:18 EDT 2017 x86_64 x86_64 x86_64 GNU/Linux
java version "1.8.0_152"
Java(TM) SE Runtime Environment (build 1.8.0_152-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.152-b16, mixed mode)
class getResource manifestURL = jar:file:/usr/java/jdk1.8.0_152/jre/lib/ext/jfxrt.jar!/META-INF/MANIFEST.MF
class getResource manifestURL = jar:file:/usr/java/jdk1.8.0_152/jre/lib/ext/jfxrt.jar!/META-INF/MANIFEST.MF
URLClassLoader getResource manifestURL = jar:file:/usr/java/jdk1.8.0_152/jre/lib/ext/jfxrt.jar!/META-INF/MANIFEST.MF
URLClassLoader findResource manifestURL = jar:file:/users/sewardge/NetBeansProjects/TestApplication/dist/TestApplication.jar!/META-INF/MANIFEST.MF


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------

TestApplication.java
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package testapplication;

/**
 *
 * @author sewardge
 */
public class TestApplication {

   static TestWindow bForm;
   
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
      bForm = new TestWindow();
      bForm.setVisible(true);
    }
    
}

TestWindow.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package testapplication;

import java.net.URL;
import java.net.URLClassLoader;


/**
 *
 * @author sewardge
 */
public class TestWindow extends javax.swing.JFrame {

    /**
     * Creates new form TestWindow
     */
    public TestWindow() {
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jButton1.setText("jButton1");
        URL manifestURL;
        manifestURL = getClass().getResource("/META-INF/MANIFEST.MF");
        System.out.println("class getResource manifestURL = " + manifestURL);
        manifestURL = TestWindow.class.getResource("/META-INF/MANIFEST.MF");
        System.out.println("class getResource manifestURL = " + manifestURL);
        manifestURL = ((URLClassLoader) TestWindow.class.getClassLoader()).getResource("META-INF/MANIFEST.MF");
        System.out.println("URLClassLoader getResource manifestURL = " + manifestURL);
        manifestURL = ((URLClassLoader) TestWindow.class.getClassLoader()).findResource("META-INF/MANIFEST.MF");
        System.out.println("URLClassLoader findResource manifestURL = " + manifestURL);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGap(132, 132, 132)
                .addComponent(jButton1)
                .addContainerGap(180, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGap(100, 100, 100)
                .addComponent(jButton1)
                .addContainerGap(175, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(TestWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(TestWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(TestWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(TestWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new TestWindow().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JPanel jPanel1;
    // End of variables declaration//GEN-END:variables
}


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

CUSTOMER SUBMITTED WORKAROUND :
The following is an excerpt from the above source codes that works for both 144 and 152.
        URL manifestURL = ((URLClassLoader) TestWindow.class.getClassLoader()).findResource("META-INF/MANIFEST.MF");
        System.out.println("URLClassLoader findResource manifestURL = " + manifestURL);



Comments
I can confirm that these entries are missing from 8u152. Nothing intentionally changed on the FX side to remove these entries, so it might be a JDK build issue. I'll check further and reassign as needed.
08-01-2018

I move this to javafx/build for further investigation (unclear if this belongs to infra/build or not). AFAICT meta-index was augmented to include entries for jfxrt.jar.
08-01-2018

As Alan said, getResource does the class loader delegation and should find the resources from the boot class path and extension directory before finding from the application JAR file. 8u151 behavior is due to the meta-index performance optimization that is generated at build time. 8u151 jre/lib/ext/meta-index includes entries for jfxrt.jar that represent the resources in jfxrt.jar. It does not list META-INF/MANIFEST.MF in jfxrt.jar and that's why it skips searching it from jfxrt.jar. meta-index for 8u152 has no entry for jfxrt.jar (we have to find out why meta-index are generated without jfxrt.jar). This explains why getResource returns jar:file:/opt/jdk/jdk1.8.0_152/jre/lib/ext/jfxrt.jar!/META-INF/MANIFEST.MF
08-01-2018

getResource does parent delegation so TestApplication.class.getResource("/META-INF/MANIFEST.MF") will first search for the resource on the boot class path, then the extensions directory, then the class path. It should not be surprising that it finds a manifest in one of the JAR files in the JDK. I can't tell if JavaFX added a manifest in 8u152. In any case, there are several issues with the test case. It incorrectly assumes the application class loader is a URLClassLoader. That will break when then move to JDK 9 or newer. Also findResource is not a public method, it cannot be used as described.
08-01-2018

Attached simiplified test case (Test.java) to verify this issue. - compile and run the program with respective JDK version $ javac Test.java $ java Test
05-01-2018

Checked with JDK 8u152 builds and confirmed that it started failing with b01.
04-01-2018

The regression has been introduced in JDK 8u152. It works fine with 8u151. Updating the results while adding introduced version value. 8u151: OK 8u152: FAIL
03-01-2018

No, the test didn't run with JDK 9 or JDK 10 ea with exception: jdk bug java.base/jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to java.base/java.net.URLClassLaoder Apparently due to the reasons with respect to new class loader implementations as stated in JDK 9 and 10 documentation as shared by submitter: ========================================= New Class Loader Implementations JDK 9 maintains the hierarchy of class loaders that existed since the 1.2 release. However, the following changes have been made to implement the module system: ���The application class loader is no longer an instance of URLClassLoader but, rather, of an internal class. It is the default loader for classes in modules that are neither Java SE nor JDK modules. The lines dealing with URLClassLoader could be dropped. They are there to show how I arrived at a workaround for the problem as it exists on 1.8.0_152. After dropping the lines with the URLClassLoader calls, JDK 9 and JDK 10 did not have the same issues as 1.8.0_152 that I could tell from the versions I obtained. So with the change in implementation due to the module system, I am not sure if updating the test case to drop the URLClassLoader lines would be valid or not. =========================================== Ref: https://docs.oracle.com/javase/9/docs/api/java/lang/ClassLoader.html
19-12-2017

Reported with: ============= JDK 8u152 and 8u144 Linux whitefly With JDK 8u152, while getting the MANIFEST.MF for a class in an application jar, jar:file:/usr/java/jdk1.8.0_152/jre/lib/ext/jfxrt.jar!/META-INF/MANIFEST.MF is received instead of jar:file:/users/sewardge/NetBeansProjects/TestApplication/dist/TestApplication.jar!/META-INF/MANIFEST.MF as expected or received wit JDK 8u144. ================================ On Ubuntu 16.0.4 LTS, verified this with attached test case and could confirm the issue in 8u152. The results differs from 8u144. Results: ======= 8u144: OK 8u152: FAIL Steps to Reproduce: ================== 1. Import the attached test case () 2. Run the script RunJar144.sh and RunJar152.sh one by one (located in TestApplication diretory) 3. Observe the output as below: a) Run with JDK 8u144: :~/NetBeansProjects/TestApplication$ ./RunJar144.sh Linux Ubuntu16 4.10.0-28-generic #32~16.04.2-Ubuntu SMP Thu Jul 20 10:19:48 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux java version "1.8.0_144" Java(TM) SE Runtime Environment (build 1.8.0_144-b01) Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode) class getResource manifestURL = jar:file:/home/testuser/NetBeansProjects/TestApplication/dist/TestApplication.jar!/META-INF/MANIFEST.MF class getResource manifestURL = jar:file:/home/testuser/NetBeansProjects/TestApplication/dist/TestApplication.jar!/META-INF/MANIFEST.MF URLClassLoader getResource manifestURL = jar:file:/home/testuser/NetBeansProjects/TestApplication/dist/TestApplication.jar!/META-INF/MANIFEST.MF URLClassLoader findResource manifestURL = jar:file:/home/testuser/NetBeansProjects/TestApplication/dist/TestApplication.jar!/META-INF/MANIFEST.MF b) Run with JDK 8u152: ======================= :~/NetBeansProjects/TestApplication$ ./RunJar152.sh Linux Ubuntu16 4.10.0-28-generic #32~16.04.2-Ubuntu SMP Thu Jul 20 10:19:48 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux java version "1.8.0_152" Java(TM) SE Runtime Environment (build 1.8.0_152-b16) Java HotSpot(TM) 64-Bit Server VM (build 25.152-b16, mixed mode) class getResource manifestURL = jar:file:/opt/jdk/jdk1.8.0_152/jre/lib/ext/jfxrt.jar!/META-INF/MANIFEST.MF class getResource manifestURL = jar:file:/opt/jdk/jdk1.8.0_152/jre/lib/ext/jfxrt.jar!/META-INF/MANIFEST.MF URLClassLoader getResource manifestURL = jar:file:/opt/jdk/jdk1.8.0_152/jre/lib/ext/jfxrt.jar!/META-INF/MANIFEST.MF URLClassLoader findResource manifestURL = jar:file:/home/testuser/NetBeansProjects/TestApplication/dist/TestApplication.jar!/META-INF/MANIFEST.MF
14-12-2017