...
Consider the class MyExceptionReporter, that subclasses ExceptionReporters with the intent of adding a logging mechanism that logs critical messages before an exception is reported. Its constructor invokes the superclass's constructor (a mandatory first step) which publishes the exception reporter, before the initialization of the subclass has concluded. Note that the subclass initialization consists of obtaining an instance of the default logger. As a result, the exception handler is set and if any exception occurs before the call to Logger.getLogger in the subclass, it is not logged. Instead, a NullPointerException is generated which may again get swallowed by the reporting mechanism. In summary, this behavior is due to the race condition between an oncoming exception and the initialization of the subclass. If the exception comes too soon, it finds the subclass in a compromised state. This behavior is even more counter intuitive because logger is declared final and is not expected to contain an unintialized value.
| Code Block | ||
|---|---|---|
| ||
// Interface ExceptionReporter
public interface ExceptionReporter {
public void setExceptionReporter(ExceptionReporter er);
public void report(Throwable exception);
}
// Class ExceptionReporters
public class ExceptionReporters implements ExceptionReporter {
public ExceptionReporters(ExceptionReporter er) {
/* Carry out initialization */
er.setExceptionReporter(this); // incorrectly publishes the "this" reference
}
public void report(Throwable exception) { /* default implementation */ }
public final void setExceptionReporter(ExceptionReporter er) { /* sets the reporter */ }
}
// Class MyExceptionReporter derives from ExceptionReporters
public class MyExceptionReporter extends ExceptionReporters {
private final Logger logger;
public MyExceptionReporter(ExceptionReporter er) {
super(er); // calls superclass's constructor
logger = Logger.getLogger("com.organization.Log");
}
public void report(Throwable t) {
logger.log(Level.FINEST,"Loggable exception occurred",t);
}
}
|
...