Why is my NullPointerException not being caught in my catch block?
Asked Answered
A

9

7

I have a thread in which I catch all errors in a big, all-encompassing catch block. I do this so that I can report any error, not just expected ones, in my application. My Runnable looks like this:

public final void run()
{
    try
    {
        System.out.println("Do things"); /* [1] */

        doUnsafeThings();
    }
    catch (Throwable t)
    {
        System.out.println("Catch"); /* [2] */

        recover();
    }
    finally
    {
        System.out.println("Finally"); /* [3] */
    }
}

I would expect the NPE to be caught by the Throwable catch block. Instead, the output at [2] is not printed, and neither is [3]. The output at [1] is printed.

What I do get on the console, is this:

Uncaught exception java/lang/NullPointerException.

What on earth is going on here?

For the court records, I'm using J2ME, and this is running in Sun's WTK v2.5.2 emulator.

I'm tempted to put it down to JVM implementation dodginess but I can't help feeling that I'm just missing something.

To clarify for the avoidance of doubt (Since the example code is obviously altered from my production code)

  • There is nothing outside of the try/catch/finally block in the run method.
  • There is a System.out.println at the start of each of those blocks - What follows those console statements should not matter.
Abixah answered 22/4, 2009 at 11:32 Comment(2)
Is the output at [1] displayed?Afoot
Oh, and can I have your autograph, Mr. Skeet? :PAbixah
A
7

The answer turns out that I'm an idiot. I'd explain what went wrong, but let's just call it "one of those bugs".

I had momentarily forgotten that the thread that ran the runnable was a custom thread class (To get round some Nokia bugs). It called run() repeatedly between calls to a canWait() method.

The canWait method was responsible for the failure, and run wasn't failing at all. To top it off, I have console-blindness and completely but accidentally misquoted the sequence of events in my question.

Abixah answered 22/4, 2009 at 13:16 Comment(2)
Inquiring minds want to know. We've all done boneheaded things.Mi
I had momentarily forgotten that the thread that ran the runnable was a custom thread class (To get round some Nokia bugs). It called run() repeatedly between calls to a 'canWait()' method. The canWait method was responsible for the failure, and run wasn't failing at all. To top it off, I have console-blindness and completely but accidentally misquoted the sequence of events in my question.Abixah
P
6

Sounds like you'll need some trial and error. May I suggest:

try {
    doEvilStuff();
} catch (NullPointerException ex) { 
    System.out.println("NPE encountered in body"); 
} catch (Throwable ex) {
    System.out.println("Regular Throwable: " + ex.getMessage());
} finally {
    etc...
}

By having an explicit catch for NullPointerException, it should become obvious if the exception is from within the try block or a catch/finally block.

Pettigrew answered 22/4, 2009 at 11:54 Comment(0)
A
4

Okay, this is a wild guess... but it would explain things.

Obviously your code isn't actually that - so my guess is that your catch (or finally) block is either doing something before it logs anything, or it uses a different logger than the try block. Either way, I suspect that either the catch or the finally block is throwing the exception.

I don't suppose you have a stack trace...

EDIT: Okay, if it's just System.out.println, is it something in the argument that might go bang? For example:

catch (Throwable t) {
    // Will go bang if t.getCause() returns null
    System.out.println(t.getCause().getMessage());
}

If it's just simple System.out.println("Constant") then it's very weird.

Do you know (e.g. from log lines within the try block) how far the try block is actually getting?

Afoot answered 22/4, 2009 at 11:46 Comment(1)
No stack trace, no (Can't catch it). And my update to my question just now addresses some of your answer. There's no logging framework involved either.. just System.out.println.Abixah
M
2

When I looked at your code it seems that recover() is throwing an exception, so the advice given by Jon would be excellent to follow.

If you gave us a stack trace you may get better help.

When I try to catch exceptions I do something like this:

try {
  doSomethingBad();
} catch(Exception e) {
   try {
      LogException(...);
   } catch(Exception e) {}       
} finally {
}

I don't like to nest exceptions, but I don't like my catch block throwing exceptions.

Monegasque answered 22/4, 2009 at 12:6 Comment(0)
C
2

As you mention you are using a Runnable - does this by any chance mean that you are using multiple threads as well? If the doUnsafeThings() method internally spawns a different thread again and that produces the exception, you might not get it in the thread your catch block is. See http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Thread.UncaughtExceptionHandler.html

Calvincalvina answered 22/4, 2009 at 13:11 Comment(0)
K
1

It is generally a bad practice to catch NullPointerException.

Programmers typically catch NullPointerException under three circumstances:

The program contains a null pointer dereference. Catching the resulting exception was easier than fixing the underlying problem.
The program explicitly throws a NullPointerException to signal an error condition.
The code is part of a test harness that supplies unexpected input to the classes under test. 

Of these three circumstances, only the last is acceptable. following this link:

Catch NullPointerException

Kraut answered 17/11, 2012 at 5:30 Comment(1)
Does makes sense. So i searched on google to get more context, anyone interested in reading more about catching NPEs -> #18266440Hospitality
A
0

Is it possible that the thread is being killed by some other code? In general a finally block always executes unless the thread is abnormally terminated, either by System.exit() or something similar.

Arris answered 22/4, 2009 at 11:40 Comment(2)
Unfortunately this is not possible. The system does not exit, and the code is built for CLDC 1.0 (Basically a subset of the Java API), which means that there is no way to terminate a thread. It's not part of the API - threads only exit when run() exits.Abixah
Can you verify that your thread is actually exiting? Is it possible the thread is still alive, but blocked due to an exception somewhere, and only appears to have died from the outside?Orlantha
S
0
  • Are you sure you are looking at the right place in the code? I.e., is the doUnsafeThings() block you are protecting in of the stack trace?

  • Maybe there is a problem with your build method, and you are debugging an old version of the code?

Submit answered 22/4, 2009 at 12:10 Comment(0)
I
0

just add some logging in the doUnsafeThings(); to see if that method is doing what you expect (e.g put a try catch finally and log something)

Incorporable answered 22/4, 2009 at 13:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.