-
Bug
-
Resolution: Not an Issue
-
P4
-
None
-
7
-
x86
-
linux
FULL PRODUCT VERSION :
java version "1.6.0"
OpenJDK Runtime Environment (build 1.6.0-b09)
OpenJDK Client VM (build 1.6.0-b09, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Linux osiris 2.6.24-16-generic #1 SMP Thu Apr 10 13:23:42 UTC 2008 i686 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
I have build my own observer pattern to get notified with messages from multiple threads. Every message will be logged in the main logger. The logger is working in the most cases, but sometimes, the method LogManager's getLogger method returns null.
In my case, the test code works 20 times, but for the 21st log message I will get a NullPointerException.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Very hard to reproduce, on my Windows machine and on my Debian Edge machine this bug is not reproducable, but it appears on Ubuntu Hardy Heron.
Maybe the method LogManager.getLogManager() does not use a double checked singleton pattern, for example:
private static volatile LogManager logManager;
static LogManager getLogManager()
{
if (LogManager.logManager == null)
{
synchronized (LogManager.class)
{
if (LogManager.logManager == null)
{
LogManager.logManager = new LogManager(...);
}
}
}
return LogManager.logManager;
}
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "Thread-3" java.lang.NullPointerException
at dataprocessor.Application.update(Application.java:150)
at plugin.base.PlugInApplication$1.update(PlugInApplication.java:186)
at plugin.message.MessageEventObservable.updateObservers(MessageEventObservable.java:98)
at plugin.base.ExecutionProcess.run(ExecutionProcess.java:220)
at java.lang.Thread.run(Thread.java:636)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public Application(final String[] args)
{
// Create a logger that writes log records into a file
final Logger logger = Logger.getLogger("Application");
logger.setLevel(Level.ALL);
try
{
final String appPath = this.getApplicationPath();
final String logFilePath = appPath + File.separator + loggerName + ".log";
final File file = new File(logFilePath);
final FileHandler fileHandler = new FileHandler(file.getAbsolutePath());
fileHandler.setFormatter(new plugin.util.DiscreteFormatter());
logger.addHandler(fileHandler);
}
catch (final Exception exception)
{
exception.printStackTrace();
}
// Add the logger to the log manager
LogManager.getLogManager().addLogger(logger);
}
@Override
public void update(final MessageEvent event)
{
final Logger logger = LogManager.getLogManager().getLogger("Application");
if (event.getLevel() == MessageEvent.FINE || event.getLevel() == MessageEvent.INFO)
{
System.out.println(event.getMessage());
logger.setUseParentHandlers(false);
}
else
{
System.err.println(event.getMessage());
logger.setUseParentHandlers(true);
}
event.log(logger);
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Do not use the LogManager class:
private final Logger logger;
public Application(final String[] args)
{
// Create a logger that writes log records into a file
this.logger = Logger.getLogger("Application");
this.logger.setLevel(Level.ALL);
try
{
final String appPath = this.getApplicationPath();
final String logFilePath = appPath + File.separator + loggerName + ".log";
final File file = new File(logFilePath);
final FileHandler fileHandler = new FileHandler(file.getAbsolutePath());
fileHandler.setFormatter(new plugin.util.DiscreteFormatter());
this.logger.addHandler(fileHandler);
}
catch (final Exception exception)
{
// Ignore exceptions
}
}
/**
* (non-Javadoc)
* @see plugin.base.PlugInApplication#update(plugin.message.MessageEvent)
*/
@Override
public void update(final MessageEvent event)
{
if (event.getLevel() == MessageEvent.FINE || event.getLevel() == MessageEvent.INFO)
{
System.out.println(event.getMessage());
this.logger.setUseParentHandlers(false);
}
else
{
this.logger.setUseParentHandlers(true);
}
event.log(this.logger);
}
java version "1.6.0"
OpenJDK Runtime Environment (build 1.6.0-b09)
OpenJDK Client VM (build 1.6.0-b09, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Linux osiris 2.6.24-16-generic #1 SMP Thu Apr 10 13:23:42 UTC 2008 i686 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
I have build my own observer pattern to get notified with messages from multiple threads. Every message will be logged in the main logger. The logger is working in the most cases, but sometimes, the method LogManager's getLogger method returns null.
In my case, the test code works 20 times, but for the 21st log message I will get a NullPointerException.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Very hard to reproduce, on my Windows machine and on my Debian Edge machine this bug is not reproducable, but it appears on Ubuntu Hardy Heron.
Maybe the method LogManager.getLogManager() does not use a double checked singleton pattern, for example:
private static volatile LogManager logManager;
static LogManager getLogManager()
{
if (LogManager.logManager == null)
{
synchronized (LogManager.class)
{
if (LogManager.logManager == null)
{
LogManager.logManager = new LogManager(...);
}
}
}
return LogManager.logManager;
}
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "Thread-3" java.lang.NullPointerException
at dataprocessor.Application.update(Application.java:150)
at plugin.base.PlugInApplication$1.update(PlugInApplication.java:186)
at plugin.message.MessageEventObservable.updateObservers(MessageEventObservable.java:98)
at plugin.base.ExecutionProcess.run(ExecutionProcess.java:220)
at java.lang.Thread.run(Thread.java:636)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public Application(final String[] args)
{
// Create a logger that writes log records into a file
final Logger logger = Logger.getLogger("Application");
logger.setLevel(Level.ALL);
try
{
final String appPath = this.getApplicationPath();
final String logFilePath = appPath + File.separator + loggerName + ".log";
final File file = new File(logFilePath);
final FileHandler fileHandler = new FileHandler(file.getAbsolutePath());
fileHandler.setFormatter(new plugin.util.DiscreteFormatter());
logger.addHandler(fileHandler);
}
catch (final Exception exception)
{
exception.printStackTrace();
}
// Add the logger to the log manager
LogManager.getLogManager().addLogger(logger);
}
@Override
public void update(final MessageEvent event)
{
final Logger logger = LogManager.getLogManager().getLogger("Application");
if (event.getLevel() == MessageEvent.FINE || event.getLevel() == MessageEvent.INFO)
{
System.out.println(event.getMessage());
logger.setUseParentHandlers(false);
}
else
{
System.err.println(event.getMessage());
logger.setUseParentHandlers(true);
}
event.log(logger);
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Do not use the LogManager class:
private final Logger logger;
public Application(final String[] args)
{
// Create a logger that writes log records into a file
this.logger = Logger.getLogger("Application");
this.logger.setLevel(Level.ALL);
try
{
final String appPath = this.getApplicationPath();
final String logFilePath = appPath + File.separator + loggerName + ".log";
final File file = new File(logFilePath);
final FileHandler fileHandler = new FileHandler(file.getAbsolutePath());
fileHandler.setFormatter(new plugin.util.DiscreteFormatter());
this.logger.addHandler(fileHandler);
}
catch (final Exception exception)
{
// Ignore exceptions
}
}
/**
* (non-Javadoc)
* @see plugin.base.PlugInApplication#update(plugin.message.MessageEvent)
*/
@Override
public void update(final MessageEvent event)
{
if (event.getLevel() == MessageEvent.FINE || event.getLevel() == MessageEvent.INFO)
{
System.out.println(event.getMessage());
this.logger.setUseParentHandlers(false);
}
else
{
this.logger.setUseParentHandlers(true);
}
event.log(this.logger);
}