It seems most likely to me that it was getting thrown and just not getting caught.
When an exception is thrown but not caught, the thread the exception was thrown in should die. If it was the main thread, the JVM will output a message to the console. If it wasn’t the main thread, the thread will just die without outputting anything to the console.
Did the NPE occur outside of the main thread? Even if you don’t have any threads of your own, it might have occurred on the AWT Event Thread.
I had a try-catch block in the main method that caught all exceptions. But when I had an exception on the AWT Event Thread or a different thread, it just caused the thread to die. At first, I started inserting try-catch blocks in all my run methods in Runnables and anywhere else I had a thread.
Then I wrote the following class:
package cg.concurrent;
import cg.error.*;
/**This class defines a Runnable that can't silently die due to an exception.
* @author Steven Fletcher
* @since 2008/02/23
* @version 2008/02/23
*/
public abstract class SafeRunnable implements Runnable {
/**Constructor.
* @param name the name of this SafeRunnable (to be output in error messages)
*/
public SafeRunnable(final String name) {
this.name = name;
} //end constructor
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
public final void run() {
try {
runSafely();
} catch(Throwable throwable) {
ErrorStream.output(throwable, ConcurrentErrorList.safeRunnableRunFailed, name);
}
} //end run
//PROTECTED METHODS//////////////////////////////////////////////////////////////////////
/**The method that will be run within a try-catch block.
*/
protected abstract void runSafely();
//VARIABLES//////////////////////////////////////////////////////////////////////////////
private final String name;
} //end class SafeRunnable
It’s just like a Runnable except that you implement the runSafely method instead of the run method.
And I put the error message in a separate file (I like to put all the error messages for a package in one file):
package cg.concurrent;
/**This class stores error messages for the cg.concurrent package.
* @author Steven Fletcher
* @since 2008/02/23
* @version 2008/02/23
*/
interface ConcurrentErrorList {
static final String safeRunnableRunFailed = "SafeRunnable [%s]'s run method failed.";
} //end interface ConcurrentErrorList