-
Bug
-
Resolution: Won't Fix
-
P4
-
6
-
x86
-
linux
FULL PRODUCT VERSION :
This code looks the same in 1.5.0_01, 1.6.0_01, and recent openjdk6 builds.
A DESCRIPTION OF THE PROBLEM :
LogManager maintains a set of "global handlers" that are initialized from the "handlers" property and applied to the root logger. These handlers are initialized lazily, and whether or not they have been initialized is tracked with the "initializedGlobalHandlers" field.
LogManager also allows users to register a PropertyChangeListener, which is notified whenever the logging configuratino changes.
Unfortunately, since initializedGlobalHandlers is set to true in the reset() method and not set to false until *after* the PropertyChangeEvent is fired, during the time that event is firing there are no global handlers registered.
For example, if a PropertyChangeListener tries to write a log message it will not go to the ConsoleHandler.
The easy fix is to move the "initializedGlobalHandlers = false;" line in LogManager.readConfiguration(InputStream) above the firePropertyChange() call.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Obtain the current LogManager.
2. Register a PropertyChangeListener that relies on the global handlers being initialized (e.g. tries to use or modify ConsoleHandler).
3. Call readConfiguration().
The global handlers will be in effect and visible immediately before and after readConfiguration(), but not while the PropertyChangeListener is invoked.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Logger.getLogger("").getHandlers() returns global handlers during propertyChangeEvent (e.g. ConsoleHandler).
ACTUAL -
Logger.getLogger("").getHandlers() returns an empty array during propertyChangeEvent because initializedGlobalHandlers is still true but reset() has already been called.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.util.logging.*;
public class LoggingGlobalHandlerTest {
public static void main(String[] args) throws IOException {
System.err.println("At start-up, handlers:");
for (Handler handler : Logger.getLogger("").getHandlers()) {
System.err.println("... " + handler);
}
LogManager.getLogManager().addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
System.err.println("During propertyChange:");
for (Handler handler : Logger.getLogger("").getHandlers()) {
System.err.println("... " + handler);
}
}
});
LogManager.getLogManager().readConfiguration();
System.err.println("After reset, handlers:");
for (Handler handler : Logger.getLogger("").getHandlers()) {
System.err.println("... " + handler);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Don't rely on PropertyChangeListener for logging configuration notifications.
This code looks the same in 1.5.0_01, 1.6.0_01, and recent openjdk6 builds.
A DESCRIPTION OF THE PROBLEM :
LogManager maintains a set of "global handlers" that are initialized from the "handlers" property and applied to the root logger. These handlers are initialized lazily, and whether or not they have been initialized is tracked with the "initializedGlobalHandlers" field.
LogManager also allows users to register a PropertyChangeListener, which is notified whenever the logging configuratino changes.
Unfortunately, since initializedGlobalHandlers is set to true in the reset() method and not set to false until *after* the PropertyChangeEvent is fired, during the time that event is firing there are no global handlers registered.
For example, if a PropertyChangeListener tries to write a log message it will not go to the ConsoleHandler.
The easy fix is to move the "initializedGlobalHandlers = false;" line in LogManager.readConfiguration(InputStream) above the firePropertyChange() call.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Obtain the current LogManager.
2. Register a PropertyChangeListener that relies on the global handlers being initialized (e.g. tries to use or modify ConsoleHandler).
3. Call readConfiguration().
The global handlers will be in effect and visible immediately before and after readConfiguration(), but not while the PropertyChangeListener is invoked.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Logger.getLogger("").getHandlers() returns global handlers during propertyChangeEvent (e.g. ConsoleHandler).
ACTUAL -
Logger.getLogger("").getHandlers() returns an empty array during propertyChangeEvent because initializedGlobalHandlers is still true but reset() has already been called.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.util.logging.*;
public class LoggingGlobalHandlerTest {
public static void main(String[] args) throws IOException {
System.err.println("At start-up, handlers:");
for (Handler handler : Logger.getLogger("").getHandlers()) {
System.err.println("... " + handler);
}
LogManager.getLogManager().addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
System.err.println("During propertyChange:");
for (Handler handler : Logger.getLogger("").getHandlers()) {
System.err.println("... " + handler);
}
}
});
LogManager.getLogManager().readConfiguration();
System.err.println("After reset, handlers:");
for (Handler handler : Logger.getLogger("").getHandlers()) {
System.err.println("... " + handler);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Don't rely on PropertyChangeListener for logging configuration notifications.