--- old/src/java.logging/share/classes/java/util/logging/LogManager.java 2014-11-04 17:20:39.000000000 +0100
+++ new/src/java.logging/share/classes/java/util/logging/LogManager.java 2014-11-04 17:20:39.000000000 +0100
@@ -31,6 +31,7 @@
import java.security.*;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
+import java.util.concurrent.CopyOnWriteArrayList;
import sun.misc.JavaAWTAccess;
import sun.misc.SharedSecrets;
@@ -100,6 +101,18 @@
* Note that these Handlers may be created lazily, when they are
* first used.
*
+ *
A property "<logger>.handlers.ensureCloseOnReset". This defines a
+ * a boolean value. If "<logger>.handlers" is not defined or is empty,
+ * this property is ignored. Otherwise it defaults to "true". When the value
+ * is "true", the loggers for which at least one handler was configured
+ * using the previous "<logger>.handlers" property will stay
+ * strongly referenced until {@code reset()} is called. This can be turned off
+ * by explicitly setting "<logger>.handlers.ensureCloseOnReset=false" in
+ * the configuration. Note that turning this property off causes the risk of
+ * introducing a resource leak, as the logger may get garbage collected before
+ * {@code reset()} is called, thus preventing its handlers from being closed
+ * on {@code reset()}.
+ *
*
A property "<logger>.useParentHandlers". This defines a boolean
* value. By default every logger calls its parent in addition to
* handling the logging message itself, this often result in messages
@@ -169,6 +182,33 @@
// True if JVM death is imminent and the exit hook has been called.
private boolean deathImminent;
+ // This list contains the loggers for which some handlers have been
+ // explicitely configured in the configuration file.
+ // It prevents these loggers from being arbitrarily garbage collected.
+ private static final class PersistentLogger {
+ private final Logger logger;
+ private PersistentLogger(Logger ref) {
+ this.logger = Objects.requireNonNull(ref);
+ }
+ @Override
+ public boolean equals(Object other) {
+ return (other instanceof PersistentLogger) && ((PersistentLogger)other).logger == logger;
+ }
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(logger);
+ }
+ public Logger get() {
+ return logger;
+ }
+ public static PersistentLogger create(Logger logger) {
+ return new PersistentLogger(logger);
+ }
+ }
+ private final CopyOnWriteArrayList persistentLoggers =
+ new CopyOnWriteArrayList<>();
+
+
private final Map