8195096: Exception printed on console with custom LogManager on starting Apache Tomcat

Make sure that loadLoggerHandler for ".handler" is called only from within addLogger

Reviewed-by: mchung
This commit is contained in:
Daniel Fuchs 2018-01-26 14:15:09 +00:00
parent cf8d43353f
commit e6c7f041f9
8 changed files with 490 additions and 20 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -396,12 +396,6 @@ public class LogManager {
// Create and retain Logger for the root of the namespace.
owner.addLogger(root);
// For backward compatibility: add any handlers configured using
// ".handlers"
owner.createLoggerHandlers("", ".handlers")
.stream()
.forEach(root::addHandler);
// Initialize level if not yet initialized
if (!root.isLevelInitialized()) {
root.setLevel(defaultLevel);
@ -995,7 +989,8 @@ public class LogManager {
}
}
private List<Handler> createLoggerHandlers(final String name, final String handlersPropertyName)
private List<Handler> createLoggerHandlers(final String name,
final String handlersPropertyName)
{
String names[] = parseClassNames(handlersPropertyName);
List<Handler> handlers = new ArrayList<>(names.length);
@ -1198,7 +1193,7 @@ public class LogManager {
}
drainLoggerRefQueueBounded();
LoggerContext cx = getUserContext();
if (cx.addLocalLogger(logger)) {
if (cx.addLocalLogger(logger) || forceLoadHandlers(logger)) {
// Do we have a per logger handler too?
// Note: this will add a 200ms penalty
loadLoggerHandlers(logger, name, name + ".handlers");
@ -1208,6 +1203,26 @@ public class LogManager {
}
}
// Checks whether the given logger is a special logger
// that still requires handler initialization.
// This method will only return true for the root and
// global loggers and only if called by the thread that
// performs initialization of the LogManager, during that
// initialization. Must only be called by addLogger.
@SuppressWarnings("deprecation")
private boolean forceLoadHandlers(Logger logger) {
// Called just after reading the primordial configuration, in
// the same thread that reads it.
// The root and global logger would already be present in the context
// by this point, but we would not have called loadLoggerHandlers
// yet.
return (logger == rootLogger || logger == Logger.global)
&& !initializationDone
&& initializedCalled
&& configurationLock.isHeldByCurrentThread();
}
// Private method to set a level on a logger.
// If necessary, we raise privilege before doing the call.
private static void doSetLevel(final Logger logger, final Level level) {