NPE's sometimes get ignored?

I just spent hours narrowing down a phantom problem, only to realize that there was a NPE being thrown, but that never hit the console for some reason. Only after I put an explicit try/catch block around the faulty code, did the NPE get thrown, but this is hardly standard protocol at all. NPE’s are thrown, regardless, right?

Is there some reason for these NPE’s to get consumed and never reported? Given the frequency of this kind of exception, this is terribly difficult to debug.

I’ve never had that happen to me. Uncaught exceptions that bubble all the way to the top of the stack (or is it bottom?) always print a stacktrace in stderr for me.

Are you sure there’s no “catch {Exception e} { /* todo: report this */}” anywhere in the code?

long shot but there could be a default exception handler that simply ignores it?

Oh, cool, I never knew that existed! I’ve learned something new today! =D

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

[quote=“fletchergames,post:5,topic:31669”]
I tested it today at work, and all threads (even daemon ones) spit out the exception to stderr when they die from exception.
I’ve got some flavor of java 1.6 at work, and this statement is based on experimentation, not documented truth.

Uncaught Throwables ALWAYS get printed to STDERR, except for ThreadDeath, if there is no user-defined DefaultExceptionHandler

This statement:[quote]If it wasn’t the main thread, the thread will just die without outputting anything to the console.
[/quote]
is false, and never ever has been true.

Just think of the debug-nightmare…

I see.

It must be something screwy with my code or with how I have my environment set up. In any case, I made it work for my situation with the SafeRunnable class.

Perhaps I was catching the exceptions and ignoring them somewhere without realizing it.