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 toJDK-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
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
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