GS-8802 , GS-9973 , GS-10078
A logging helper class used to avoid a deadlock situation when
java.util.logging is initializing, while it is also being referenced by utility classes.
The
RollingFileHandler
resolves its PID, host, and homedir properties by calling utility
classes, which also try to reference a Logger using
Logger.getLogger(String)
.
This
causes a deadlock in JDK logging, since our custom handler is already called after holding a lock
on
LogManager
class and it is trying to also get a lock on
Logger
class when
calling
Logger.getLogger(String)
from utility classes.
When another thread calls
Logger.getLogger(String)
it in turn calls LogManager.demandLogger(..) which locks
LogManager
on a call to
LogManager.getLogger(String)
.
Deadlock:
lock [LogManager.class] -> LogManager.initializeGlobalHandlers() ->
RollingFileHandler.resolveProperty(..) -> wait to lock [Logger.class] on call to
Logger.getLogger(..)
lock [Logger.class] -> Logger.getLogger() -> LogManager.demandLogger()
-> wait to lock [LogManager.class] on call to LogManager.getLogger()
This helper class is intended to be called by utility classes which need to log messages. We go
through
LogManager.getLogger(String)
to avoid the deadlock. It may return
null
if not yet initialized, in such a case we try to flush it to system.out/err.