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

Issue with JNLPClassLoader in ShutdownHook

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P4
    • Resolution: Won't Fix
    • Affects Version/s: 7u65
    • Fix Version/s: None
    • Component/s: deploy
    • Labels:
    • Subcomponent:
    • CPU:
      x86_64
    • OS:
      linux

      Description

      FULL PRODUCT VERSION :
      java version "1.7.0_65"
      Java(TM) SE Runtime Environment (build 1.7.0_65-b17)
      Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Linux 3.13.0-24-generic #47-Ubuntu SMP Fri May 2 23:30:00 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

      Reproducible also on Windows 7, Windows 8

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      The bug appear only when running the application on Java Web Start.


      A DESCRIPTION OF THE PROBLEM :
      The problem appears in the shutdown hook exclusively when running with Java Web Start (JWS).

      It could be related to JDK-8012912 and JDK-8015931.

      I try to make the test case (Message.java ) as simple as possible. When launching the test case with JWS an exception is thrown when calling new Runnable().

      The problem seems to be related with JNLPClassLoader which not finding anonymous class and also with enum variables.




      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1) Compile and sign the test case with maven:
      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>org.test</groupId>
      <artifactId>message</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <name>Message</name>
      <packaging>jar</packaging>
      <build>
      <plugins>
      <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.1</version>
      <configuration>
      <source>1.7</source>
      <target>1.7</target>
      </configuration>
      </plugin>
      <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jar-plugin</artifactId>
      <version>2.4</version>
      <configuration>
      <archive>
      <index>true</index>
      <manifest>
      <addClasspath>true</addClasspath>
      </manifest>
      <manifestEntries>
      <Permissions>all-permissions</Permissions>
      <Application-Name>Warning Message</Application-Name>
      <Trusted-Library>true</Trusted-Library>
      <Codebase>*</Codebase>
      <Application-Library-Allowable-Codebase>*</Application-Library-Allowable-Codebase>
      <Caller-Allowable-Codebase>*</Caller-Allowable-Codebase>
      </manifestEntries>
      </archive>
      <finalName>${project.artifactId}</finalName>
      </configuration>
      </plugin>
      <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jarsigner-plugin</artifactId>
      <version>1.2</version>
      <executions>
      <execution>
      <goals>
      <goal>sign</goal>
      </goals>
      </execution>
      </executions>
      <configuration>
      </configuration>
      </plugin>
      </plugins>
      </build>
      </project>


      2) Create a jnlp file:
      <?xml version="1.0" encoding="UTF-8"?>
      <jnlp spec="1.6+" codebase="">
      <information>
      <title>Message</title>
      <vendor>No</vendor>
      </information>

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

      <resources>
      <j2se version="1.7.0_45+" href="http://java.sun.com/products/autodl/j2se"/>
      <jar href="target/message.jar" main="true" />
      </resources>
      <application-desc main-class="test.Message" />
      </jnlp>

      3) run the command: javaws launcher.jnlp

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Aug 01, 2014 4:08:03 PM test.Message main
      INFO: Add Shutdown Hook.
      Aug 01, 2014 4:08:08 PM test.Message$1 run
      INFO: Inside Shutdown Hook.
      Aug 01, 2014 4:08:08 PM test.Message$1$1 run
      INFO: Success to instantiate a Thread!
      Aug 01, 2014 4:08:08 PM test.Message$1$2 run
      INFO: Success to instantiate a Runnable!

      ACTUAL -
      Aug 01, 2014 3:59:59 PM test.Message main
      INFO: Add Shutdown Hook.
      Aug 01, 2014 4:00:04 PM test.Message$1 run
      INFO: Inside Shutdown Hook.
      Aug 01, 2014 4:00:13 PM test.Message$1$1 run
      INFO: Success to instantiate a Thread!
      Aug 01, 2014 4:06:06 PM test.Message$1 run
      SEVERE: Failed to instantiate a Runnable!
      java.lang.IllegalStateException: zip file closed
      at java.util.zip.ZipFile.ensureOpen(ZipFile.java:634)
      at java.util.zip.ZipFile.getEntry(ZipFile.java:305)
      at java.util.jar.JarFile.getEntry(JarFile.java:227)
      at com.sun.deploy.cache.CachedJarFile.getEntry(Unknown Source)
      at java.util.jar.JarFile.getJarEntry(JarFile.java:210)
      at com.sun.deploy.security.DeployURLClassPath$JarLoader.getResource(Unknown Source)
      at com.sun.deploy.security.DeployURLClassPath.getResource(Unknown Source)
      at java.net.URLClassLoader$1.run(URLClassLoader.java:358)
      at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
      at java.security.AccessController.doPrivileged(Native Method)
      at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
      at com.sun.jnlp.JNLPClassLoader.findClass(Unknown Source)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
      at test.Message$1.run(Message.java:75)

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      java.lang.IllegalStateException: zip file closed
      at java.util.zip.ZipFile.ensureOpen(ZipFile.java:634)
      at java.util.zip.ZipFile.getEntry(ZipFile.java:305)
      at java.util.jar.JarFile.getEntry(JarFile.java:227)
      at com.sun.deploy.cache.CachedJarFile.getEntry(Unknown Source)
      at java.util.jar.JarFile.getJarEntry(JarFile.java:210)
      at com.sun.deploy.security.DeployURLClassPath$JarLoader.getResource(Unknown Source)
      at com.sun.deploy.security.DeployURLClassPath.getResource(Unknown Source)
      at java.net.URLClassLoader$1.run(URLClassLoader.java:358)
      at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
      at java.security.AccessController.doPrivileged(Native Method)
      at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
      at com.sun.jnlp.JNLPClassLoader.findClass(Unknown Source)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
      at test.Message$1.run(Message.java:75)

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      package test;

      import java.io.File;
      import java.util.Timer;
      import java.util.TimerTask;
      import java.util.logging.FileHandler;
      import java.util.logging.Level;
      import java.util.logging.LogManager;
      import java.util.logging.Logger;
      import java.util.logging.SimpleFormatter;

      public class Message {

          static {
              // Workaround to keep logger alive in ShutdownHook. Must be called before any Logger method is used.
              System.setProperty("java.util.logging.manager", MyLogManager.class.getName());
          }

          public static class MyLogManager extends LogManager {
              static MyLogManager instance;

              public MyLogManager() {
                  instance = this;
              }

              @Override
              public void reset() { /* don't reset yet. */
              }

              private void reset0() {
                  super.reset();
              }

              public static void resetFinally() {
                  instance.reset0();
              }
          }

          final static Logger logger = Logger.getLogger("log");
          final static FileHandler fileHandler = getFileHandler();

          final static FileHandler getFileHandler() {
              try {
                  return new FileHandler(System.getProperty("user.dir") + File.separator + "logFile.txt");
              } catch (Exception e) {
                  e.printStackTrace();
              }
              return null;
          }

          public static void main(String[] args) {
              try {
                  logger.addHandler(fileHandler);
                  SimpleFormatter formatter = new SimpleFormatter();
                  fileHandler.setFormatter(formatter);
              } catch (SecurityException e) {
                  e.printStackTrace();
              }
              logger.log(Level.INFO, "Add Shutdown Hook.");
              Runtime.getRuntime().addShutdownHook(new Thread("Shutdown Hook") {

                  @Override
                  public void run() {
                      logger.log(Level.INFO, "Inside Shutdown Hook.");
                      try {
                          Thread thread = new Thread("Exit") {

                              @Override
                              public void run() {
                                  logger.log(Level.INFO, "Success to instantiate a Thread!");
                              }
                          };
                          thread.run();

                          Runnable runnable = new Runnable() {

                              @Override
                              public void run() {
                                  logger.log(Level.INFO, "Success to instantiate a Runnable!");
                              }
                          };

                          runnable.run();
                      } catch (Exception ex) {
                          logger.log(Level.SEVERE, "Failed to instantiate a Runnable!", ex); //$NON-NLS-1$
                      } finally {
                          MyLogManager.resetFinally();
                          Timer timer = new Timer();
                          timer.schedule(new HaltTask(), 7000);
                      }
                  }
              });

              try {
                  Thread.currentThread().sleep(5000);
              } catch (InterruptedException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }

              System.exit(0);
          }

          static class HaltTask extends TimerTask {
              @Override
              public void run() {
                  logger.log(Level.INFO, "Force to close the application with halt()");
                  fileHandler.flush();
                  Runtime.getRuntime().halt(1);
              }
          }

      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      No workaround found

        Attachments

          Activity

            People

            • Assignee:
              herrick Andy Herrick
              Reporter:
              webbuggrp Webbug Group
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: