Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8042683

Wrong Swing Event ClassLoader when Webstart of JRE 7u40 launches an older JVM

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Won't Fix
    • Icon: P3 P3
    • None
    • 7u40
    • deploy

      FULL PRODUCT VERSION :
      java version "1.7.0_40"
      Java(TM) SE Runtime Environment (build 1.7.0_40-b43)
      Java HotSpot(TM) 64-Bit Server VM (build 24.0-b56, mixed mode)

      in conjunction with

      java version "1.6.0_45"
      Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
      Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)

      But also tested with the following older versions: 1.6.0_33, 1.6.0_43

      ADDITIONAL OS VERSION INFORMATION :
      Windows 7 Professional
      Service Pack 1

      A DESCRIPTION OF THE PROBLEM :
      The Problem as described in http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8017776 is partially still there, allthough it claims to be fixed as backport according to http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8020626.

      If you start a webstart aplication for 1.7.0 the bug is fixed. But if your webstart application needs an older JRE the bug reappears.

      Since we have many customers, who have not yet requested a migration of our product to Java 7 but still want to install 1.7.0_40 for other Java applications or merely due to security issues, this is a major drawback for those customers. At the moment we advise them not to upgrade neither to 1.7.0_25 nor to 1.7.0_40.


      REGRESSION. Last worked in version 7u17

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Install JDK 1.6.0 (either update 33, 43 or 45)
      2. Install JDK 1.7.0_40
      3. Run the Ant-Script with Java 6 to get a test7u40.war
      4. Deploy the WAR file to a Servlet-Container on "localhost" (I used Tomcat)
      5. Export the Certificate of the WAR by calling
         keytool -export -keystore testkeystore -alias just4testing -rfc -storepass secret >TestCert.p12
         in the directory of the build file
      6. Import the Certificate as "Signer CA" in the Java Control Panel
      7. Open http://localhost:8081/test7u40/index.html and click on the link to start the webapp with Java 1.6.


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      ClassLoader and Context-ClassLoader should both be the JNLP ClassLoader.

      The textfield in the frame should contain something like:
      Class-ClassLoader: com.sun.jnlp.JNLPClassLoader@6c6e70c7
      Context-ClassLoader: com.sun.jnlp.JNLPClassLoader@6c6e70c7

      ACTUAL -
      The context ClassLoader of the Swing EventDispatchThread is sun.misc.Launcher$AppClassLoader at first.

      The textfield contains:
      Class-ClassLoader: com.sun.jnlp.JNLPClassLoader@6c6e70c7
      Context-ClassLoader: sun.misc.Launcher$AppClassLoader@4aad3ba4


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      NOTE: Put all sources in the same directory.

      ------- BEGIN OF TestFrame.java -------
      import java.awt.*;
      import java.awt.event.*;

      import javax.swing.*;
      import javax.swing.border.*;

      public class TestFrame extends JFrame {

          private JPanel contentPane;
          private final JScrollPane scrollPane = new JScrollPane();
          private final JTextPane txtInfo = new JTextPane();
          private final JButton btnRepair = new JButton("Repair!");

          /**
           * Launch the application.
           */
          public static void main(String[] args) {
              System.err.println("main:");
              System.err.println(getClassLoaderInfo(TestFrame.class));
              SwingUtilities.invokeLater(new Runnable() {
                  public void run() {
                      System.err.println("
      EventDispatchThread:");
                      System.err.println(getClassLoaderInfo(TestFrame.class));
                      try {
                          TestFrame frame = new TestFrame();
                          frame.setVisible(true);
                      } catch (Exception e) {
                          e.printStackTrace();
                      }
                  }
              });
          }

          /**
           * Create the frame.
           */
          public TestFrame() {
              setTitle("Test 7u40 ClassLoader");
              initialize();

              fillInfo();
              
              this.pack();
              this.setLocationRelativeTo(null);
          }

          private void initialize() {
              setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              this.scrollPane.setViewportView(this.txtInfo);
              this.btnRepair.addActionListener(new ActionListener() {
                  public void actionPerformed(ActionEvent e) {
                      repair();
                  }
              });
              this.contentPane = new JPanel();
              this.contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
              this.contentPane.setLayout(new BorderLayout(0, 0));
              this.contentPane.add(this.scrollPane, BorderLayout.CENTER);
              this.contentPane.add(this.btnRepair, BorderLayout.EAST);
              setContentPane(this.contentPane);
          }

          private void repair() {
              SwingUtilities.invokeLater(new Runnable() {
                  @Override
                  public void run() {
                      fillInfo();
                  }
              });
              throw new ThreadDeath();
          }
          
          private void fillInfo() {
              this.txtInfo.setText(getClassLoaderInfo(this.getClass()));
          }

          private static String getClassLoaderInfo(Class clazz) {
              return "Class-ClassLoader: " + clazz.getClassLoader() + "
      "
                      + "Context-ClassLoader: " + Thread.currentThread().getContextClassLoader();
          }

      }
      ------- END OF TestFrame.java -------

      ------- BEGIN OF ANT SCRIPT build.xml -------
      <project name="Test7u40" default="build">

          <property environment="env"/>
          
          <target name="build" description="makes Test WAR">
              <echo>${java.version}</echo>
              
              <javac srcdir="." debug="true" debuglevel="lines,vars,source"/>

              <!-- generate a new certificate -->
              <delete file="testkeystore"/>
              <genkey alias="just4testing" keystore="testkeystore" storepass="secret"
                  validity="365">
                  <dname>
                      <param name="CN" value="Test Certificate"/>
                  </dname>
              </genkey>

              <jar destfile="test7u40.jar" duplicate="fail" update="false">
                  <fileset dir=".">
                      <include name="*.class"/>
                  </fileset>
              </jar>

              <signjar jar="test7u40.jar" alias="just4testing" storepass="secret" keystore="testkeystore"/>
              
              <!-- create web archive -->
              <war destfile="test7u40.war" update="false" duplicate="fail" needxmlfile="false">
                  <fileset dir=".">
                      <include name="*.jar"/>
                      <include name="*.jnlp"/>
                      <include name="*.html"/>
                  </fileset>
              </war>
              <signjar jar="test7u40.war" alias="just4testing" storepass="secret" keystore="testkeystore"/>

              <!-- delete local jar and war -->
              <delete dir=".">
                  <include name="*.jar"/>
                  <include name="*.class"/>
              </delete>

              <!-- uncomment to automatically deploy web archive to Tomcat -->
              <!-- copy todir="${env.CATALINA_HOME}\webapps" overwrite="true">
                  <fileset file="test7u40.war"/>
              </copy -->
              
          </target>

      </project>
      ------- END OF ANT SCRIPT build.xml -------

      ------- BEGIN OF index.html -------
      <!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
      <html>
      <head>
          <title>Test for Java 1.7.0_40 Webstart ClassLoader</title>
      </head>
      <body>
          <h1>Test for Java 1.7.0_40 Webstart ClassLoader</h1>
          <h2><a href="startWith1.6.jnlp">Start With Java 1.6 (broken)</a></h2></body>
          <h2><a href="startWith1.7.jnlp">Start With Java 1.7 (okay)</a></h2></body>
      </html>
      ------- END OF index.html -------

      ------- BEGIN OF JNLP startWith1.6.jnlp -------
      <?xml version="1.0" encoding="utf-8"?>

      <jnlp spec="1.0+" codebase="http://localhost:8081/test7u40">

          <information>
              <title>Test for Java 1.7.0_40 ClassLoader</title>
              <vendor>Test Vendor</vendor>
          </information>

          <security>
              <all-permissions/>
          </security>

          <resources>
              <j2se version="1.6.0"/>
              <jar href="test7u40.jar"/>
          </resources>

          <application-desc main-class="TestFrame"/>

      </jnlp>
      ------- END OF JNLP startWith1.6.jnlp -------

      ------- BEGIN OF JNLP startWith1.7.jnlp -------
      <?xml version="1.0" encoding="utf-8"?>

      <jnlp spec="1.0+" codebase="http://localhost:8081/test7u40">

          <information>
              <title>Test for Java 1.7.0_40 ClassLoader</title>
              <vendor>Test Vendor</vendor>
          </information>

          <security>
              <all-permissions/>
          </security>

          <resources>
              <j2se version="1.7.0"/>
              <jar href="test7u40.jar"/>
          </resources>

          <application-desc main-class="TestFrame"/>

      </jnlp>
      ------- END OF JNLP startWith1.7.jnlp -------
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      1. Kill the EventDipatchThread. Subsequently started EventDipatchThreads have the right context ClassLoader. You can see this by clicking the "Repair"-Button in the sample class.
      2. Migrate affected Applications to Java 7.

      As already stated, both possibilities are not an option for us, since our customers owned a very well running system, as long as they did not install Java 7u25 or 7u40. When they update the cannot even login to our application, since the user Textfield will not be shown (which is a caused by this bug as a consequence of the fact that we use a customized look and feel).
      At the moment we simply advice our customers NOT to upgrade, which I think is not the preferred solution neither for them nor for ORACLE.

            dmarkov Dmitry Markov
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: