-
Bug
-
Resolution: Fixed
-
P3
-
8, 9
-
b143
-
generic
-
generic
FULL PRODUCT VERSION :
java version "1.8.0_66"
Java(TM) SE Runtime Environment (build 1.8.0_66-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
The LogManager$Cleaner thread will attempt to close all handlers when the JVM is shutdown. This is done by invoking the LogManager.resetLogger method. That method attempts to close each attached handler and ignores any checked or unchecked exception that happens to be thrown from the attached handler. This is done so all remaining handlers are closed even if there is an error encountered.
When running under GlassFish there are cases where the OSGI bundle used by a handler is shutdown before the cleaner thread is run. In which case calling Handler.close can throw a form of a LinkageError which will prevent any remaining handlers from being closed.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
NoClassDefFoundError can be generated by simply calling Handler.reportError with an exception. By the time the cleaner runs the remapped System.err classloader has been shutdown. This is described in https://java.net/jira/browse/GLASSFISH-21258
ExceptionInInitializerError can be generated on GF3 when the MailHandler is installed as an OSGI component. In this case, the JavaMail module shutdown and close method fails trying to load the JavaMail classes.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
LinkageError thrown from close should be ignored so all handlers are closed. LinkageError thrown ErrorManager created in System.err should ignored in Handler.reportError.
ACTUAL -
The cleaner stops trying to close other handlers.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.NoClassDefFoundError: com/sun/common/util/logging/LoggingOutputStream$StackTraceObjects
at com.sun.common.util.logging.LoggingOutputStream$LoggingPrintStream.println(LoggingOutputStream.java:231)
at java.lang.Throwable$WrappedPrintStream.println(Throwable.java:748)
at java.lang.Throwable.printStackTrace(Throwable.java:655)
at java.lang.Throwable.printStackTrace(Throwable.java:643)
at java.lang.Throwable.printStackTrace(Throwable.java:634)
at java.util.logging.ErrorManager.error(ErrorManager.java:96)
at java.util.logging.Handler.reportError(Handler.java:241)
at com.sun.mail.util.logging.MailHandler.reportError(MailHandler.java:1351)
at com.sun.mail.util.logging.MailHandler.send(MailHandler.java:2358)
at com.sun.mail.util.logging.MailHandler.close(MailHandler.java:749)
at java.util.logging.LogManager.resetLogger(LogManager.java:1346)
at java.util.logging.LogManager.reset(LogManager.java:1332)
at java.util.logging.LogManager$Cleaner.run(LogManager.java:239)
Caused by: java.lang.ClassNotFoundException: Unable to load class 'com.sun.common.util.logging.LoggingOutputStream$StackTraceObjects' because the bundle wiring for org.glassfish.main.common.util is no longer valid.
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1494)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
and
Exception in thread "Thread-0" java.lang.ExceptionInInitializerError
at com.sun.mail.util.logging.MailHandler.writeLogRecords0(MailHandler.java:2756)
at com.sun.mail.util.logging.MailHandler.writeLogRecords(MailHandler.java:2721)
at com.sun.mail.util.logging.MailHandler.close(MailHandler.java:837)
at java.util.logging.LogManager.resetLogger(LogManager.java:1192)
at java.util.logging.LogManager.reset(LogManager.java:1178)
at java.util.logging.LogManager$Cleaner.run(LogManager.java:256)
Caused by: java.lang.NullPointerException
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1432)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:72)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1843)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at javax.mail.internet.MimeMessage.<clinit>(MimeMessage.java:1759)
... 6 more
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
public class Closers extends Handler {
private static final Closers[] closers = new Closers[]{
new Closers(), new Closers(), new Closers()
};
private static final Logger logger = Logger.getLogger("test");
private static final Logger global = Logger.getGlobal();
private volatile boolean closed;
public static void main(String[] args) {
logger.addHandler(closers[0]);
logger.addHandler(closers[1]);
global.addHandler(closers[2]);
}
@Override
public void publish(LogRecord record) {
}
@Override
public void flush() {
}
@Override
public void close() throws SecurityException {
closed = true;
PrintStream ps = new PrintStream(new FileOutputStream(FileDescriptor.out));
ps.println(Arrays.toString(closers));
//throw new RuntimeException();
throw new LinkageError();
}
@Override
public String toString() {
return super.toString() + "{closed=" + closed + '}';
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Patch any custom handlers to to trap LinkageError from Handler.reportError
java version "1.8.0_66"
Java(TM) SE Runtime Environment (build 1.8.0_66-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
The LogManager$Cleaner thread will attempt to close all handlers when the JVM is shutdown. This is done by invoking the LogManager.resetLogger method. That method attempts to close each attached handler and ignores any checked or unchecked exception that happens to be thrown from the attached handler. This is done so all remaining handlers are closed even if there is an error encountered.
When running under GlassFish there are cases where the OSGI bundle used by a handler is shutdown before the cleaner thread is run. In which case calling Handler.close can throw a form of a LinkageError which will prevent any remaining handlers from being closed.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
NoClassDefFoundError can be generated by simply calling Handler.reportError with an exception. By the time the cleaner runs the remapped System.err classloader has been shutdown. This is described in https://java.net/jira/browse/GLASSFISH-21258
ExceptionInInitializerError can be generated on GF3 when the MailHandler is installed as an OSGI component. In this case, the JavaMail module shutdown and close method fails trying to load the JavaMail classes.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
LinkageError thrown from close should be ignored so all handlers are closed. LinkageError thrown ErrorManager created in System.err should ignored in Handler.reportError.
ACTUAL -
The cleaner stops trying to close other handlers.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.NoClassDefFoundError: com/sun/common/util/logging/LoggingOutputStream$StackTraceObjects
at com.sun.common.util.logging.LoggingOutputStream$LoggingPrintStream.println(LoggingOutputStream.java:231)
at java.lang.Throwable$WrappedPrintStream.println(Throwable.java:748)
at java.lang.Throwable.printStackTrace(Throwable.java:655)
at java.lang.Throwable.printStackTrace(Throwable.java:643)
at java.lang.Throwable.printStackTrace(Throwable.java:634)
at java.util.logging.ErrorManager.error(ErrorManager.java:96)
at java.util.logging.Handler.reportError(Handler.java:241)
at com.sun.mail.util.logging.MailHandler.reportError(MailHandler.java:1351)
at com.sun.mail.util.logging.MailHandler.send(MailHandler.java:2358)
at com.sun.mail.util.logging.MailHandler.close(MailHandler.java:749)
at java.util.logging.LogManager.resetLogger(LogManager.java:1346)
at java.util.logging.LogManager.reset(LogManager.java:1332)
at java.util.logging.LogManager$Cleaner.run(LogManager.java:239)
Caused by: java.lang.ClassNotFoundException: Unable to load class 'com.sun.common.util.logging.LoggingOutputStream$StackTraceObjects' because the bundle wiring for org.glassfish.main.common.util is no longer valid.
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1494)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
and
Exception in thread "Thread-0" java.lang.ExceptionInInitializerError
at com.sun.mail.util.logging.MailHandler.writeLogRecords0(MailHandler.java:2756)
at com.sun.mail.util.logging.MailHandler.writeLogRecords(MailHandler.java:2721)
at com.sun.mail.util.logging.MailHandler.close(MailHandler.java:837)
at java.util.logging.LogManager.resetLogger(LogManager.java:1192)
at java.util.logging.LogManager.reset(LogManager.java:1178)
at java.util.logging.LogManager$Cleaner.run(LogManager.java:256)
Caused by: java.lang.NullPointerException
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1432)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:72)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1843)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at javax.mail.internet.MimeMessage.<clinit>(MimeMessage.java:1759)
... 6 more
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
public class Closers extends Handler {
private static final Closers[] closers = new Closers[]{
new Closers(), new Closers(), new Closers()
};
private static final Logger logger = Logger.getLogger("test");
private static final Logger global = Logger.getGlobal();
private volatile boolean closed;
public static void main(String[] args) {
logger.addHandler(closers[0]);
logger.addHandler(closers[1]);
global.addHandler(closers[2]);
}
@Override
public void publish(LogRecord record) {
}
@Override
public void flush() {
}
@Override
public void close() throws SecurityException {
closed = true;
PrintStream ps = new PrintStream(new FileOutputStream(FileDescriptor.out));
ps.println(Arrays.toString(closers));
//throw new RuntimeException();
throw new LinkageError();
}
@Override
public String toString() {
return super.toString() + "{closed=" + closed + '}';
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Patch any custom handlers to to trap LinkageError from Handler.reportError