Catching NPEs

F

Frank

Is it possible to catch (and hence respond to) Null Pointer Exceptions that
could occur anywhere within my application? I thought of wrapping the
main() method in a try/catch block catching Exception or something along
those lines but I can't see how to get it to work.

-F
 
D

Daniel Dyer

Is it possible to catch (and hence respond to) Null Pointer Exceptions
that
could occur anywhere within my application? I thought of wrapping the
main() method in a try/catch block catching Exception or something along
those lines but I can't see how to get it to work.

You can, but why would you want to? NullPointerExceptions are generally
bugs that need to be fixed by changing the code. Even if you catch them,
how will you recover? You won't know which reference was null so doing
anything meaningful is pretty much impossible.

This method will help you deal with unexpected exceptions:

<http://java.sun.com/j2se/1.5.0/docs...er(java.lang.Thread.UncaughtExceptionHandler)>

Dan.
 
E

Eric Sosman

Frank said:
Is it possible to catch (and hence respond to) Null Pointer Exceptions that
could occur anywhere within my application? I thought of wrapping the
main() method in a try/catch block catching Exception or something along
those lines but I can't see how to get it to work.

You can catch them, but it's not clear how you should
"respond" to them. Remember, the context where the exception
was thrown is long gone: the call stack has been unwound all
the way up to the level of your try/catch, any finally blocks
along the way have been executed, and so on. You can "respond"
by printing a message or something, but you do not have the
option to "repair and resume."

Also, catching Exception is an awfully dull tool: it catches
everything you want along with everything you don't want. If
you write catch(Exception e) you will catch NullPointerException,
but you will catch IllegalArgumentException and ArithmeticException
and a host of others along with it. Unless you are prepared to do
something intelligent about all these different Exceptions, it is
unlikely to be a good idea to spread your net quite so widely.
 
O

Oliver Wong

Frank said:
Is it possible to catch (and hence respond to) Null Pointer Exceptions
that could occur anywhere within my application? I thought of wrapping
the main() method in a try/catch block catching Exception or something
along those lines but I can't see how to get it to work.

As Daniel said, what you're doing sounds like a bad idea, and you should
go one abstraction level higher and investigate what it is you're trying to
achieve via this blind catching, and solve it in some other manner.

That said, wrapping the main method in a try/catch block will work, as
long as the NPE is thrown in the same thread as the one your main method is
run in (most threads other than the main one won't ever go through your main
method though). If you're having problem with the syntax, it should look
something like this (not compiled nor tested):

<code>
public class Hello {
public static void main(String[] args) {
try {
System.out.println("Hello World!");
} catch (NullPointerException npe) {
/*do something*/
}
}
}
</code>

- Oliver
 
E

Ed

Daniel Dyer skrev:
You can, but why would you want to?

Well, I'm no user-experience expert (WINUEE - an unstrangely seldom
quoted newsgroup abbreviation) but when a program crashes while trying
to do something, it can be helpful if the program itself stays running,
so that something else can be attempted.

If a user is running a video-conversion program, for example, and tries
to convert a .avi to a .mpeg, and the conversion fails horribly because
of a software error in the mpeg-to-avi method, then he will probably
rather the program to print a big, dirty, "PROGRAM ERROR DURING
CONVERSION," dialog box (which the user can click and then try use the
same program to do some other conversion) than just crash and have the
user start the program again (if he has the patience).

Just a thought.

..ed
 
G

Guest

Daniel said:
You can, but why would you want to? NullPointerExceptions are generally
bugs that need to be fixed by changing the code. Even if you catch
them, how will you recover? You won't know which reference was null so
doing anything meaningful is pretty much impossible.

It is usually consider bad practice to present
a stack trace to the end user.

If the application has state in memory that needs to be
persisted it is a very good idea to save the data
before exiting.

If it is a server type application it would be a good idea
to either just terminate one thread and let the other threads
continue serving their clients or at least restart the entire
server app.

I think that in most real world applications you would catch
that kind of exceptions.

Arne
 
A

Andrew Thompson

Ed said:
Daniel Dyer skrev:


Well, I'm no user-experience expert (WINUEE - an unstrangely seldom
quoted newsgroup abbreviation) but when a program crashes while trying
to do something, it can be helpful if the program itself stays running,
so that something else can be attempted.

If a user is running a video-conversion program, for example, and tries
to convert a .avi to a .mpeg, and the conversion fails horribly because
of a software error in the mpeg-to-avi method, ...

Hmmm... sounds as though you are describing
"..bugs that need to be fixed by changing the code."
Just a thought.

Just an (unattributed) quote. ;-)

Andrew T.
 
F

Frank

Daniel Dyer said:
You can, but why would you want to? NullPointerExceptions are generally
bugs that need to be fixed by changing the code. Even if you catch them,
how will you recover? You won't know which reference was null so doing
anything meaningful is pretty much impossible.

This method will help you deal with unexpected exceptions:

<http://java.sun.com/j2se/1.5.0/docs...er(java.lang.Thread.UncaughtExceptionHandler)>

Thanks. The reason I wanted to catch these exceptions is so I could log
them. It's one thing to have your IDE handle exceptions for you but when
the application is deployed to the field you need to know what exceptions
they get. This method you quoted to set the default uncaught exception
handler is just what I was looking for.

-F
 
C

Christopher Benson-Manica

Andrew Thompson said:
Ed wrote:
Hmmm... sounds as though you are describing
"..bugs that need to be fixed by changing the code."

Yes, but while the developers are tracking down those bugs and
changing the code, it's helpful to end-users if the application
retains as much functionality as possible in the meantime.
 
J

jupiter

Arne Vajhøj said:
It is usually consider bad practice to present
a stack trace to the end user.

If the application has state in memory that needs to be
persisted it is a very good idea to save the data
before exiting.

What data if it's affected by the null reference?

I could see getting into a lot of trouble trying to save data
gracefully after a NPE.
 
C

Christopher Benson-Manica

What data if it's affected by the null reference?

There might be other data not affected by the null reference, and the
user will certainly appreciate the opportunity to at least save
partial data if possible.
I could see getting into a lot of trouble trying to save data
gracefully after a NPE.

Of course it may not be trivial to save data gracefully after a NPE,
but the attempt will probably not be optional for all but the most
trivial data.
 
J

jupiter

Christopher Benson-Manica said:
Of course it may not be trivial to save data gracefully after a
NPE,
but the attempt will probably not be optional for all but the
most
trivial data.

Got it.
 
D

Daniel Dyer

Yes, but while the developers are tracking down those bugs and
changing the code, it's helpful to end-users if the application
retains as much functionality as possible in the meantime.

I think there is potentially a distinction between server apps and desktop
apps. In desktop applications, your approach is a good idea from a user
perspective, but even then you can make no assumptions about the
consistency of the application's state. In a server application, a
NullPointerException on a critical path will effectively take down the
server. Other than logging the stack-trace and rolling back the current
transaction, there is little that can be done. If subsequent transactions
depend on the one that failed, we have a big problem.

While I take your point that the impact on the end user can be lessened,
NullPointerExceptions are alway unexpected occurrences (unless you are
doing something dubious). Additionally, unlike other exceptional
conditions such as I/O failure, it is always possible to write your code
in such a way as to avoid the problem. It is unreasonable to expect the
application to be able to rationally handle a situation that is caused by
its own deficiencies.

It may be easier said than done, but the only way around this is the
helpful solution suggested by an anonymous project manager: "well, don't
write any bugs then".

Dan.
 
E

Ed

Daniel Dyer skrev:
I think there is potentially a distinction between server apps and desktop
apps. In desktop applications, your approach is a good idea from a user
perspective, but even then you can make no assumptions about the
consistency of the application's state. In a server application, a
NullPointerException on a critical path will effectively take down the
server. Other than logging the stack-trace and rolling back the current
transaction, there is little that can be done. If subsequent transactions
depend on the one that failed, we have a big problem.

While I take your point that the impact on the end user can be lessened,
NullPointerExceptions are alway unexpected occurrences (unless you are
doing something dubious). Additionally, unlike other exceptional
conditions such as I/O failure, it is always possible to write your code
in such a way as to avoid the problem. It is unreasonable to expect the
application to be able to rationally handle a situation that is caused by
its own deficiencies.

It may be easier said than done, but the only way around this is the
helpful solution suggested by an anonymous project manager: "well, don't
write any bugs then".

Dan.

Yes, good points.

Actually, I'm embarrassed to say that I didn't really appreciate that
the OP was talking about NullPointerExceptions in particular (as
opposed to, say, memory or I/O exceptions), which seriously compromised
my point.

I'm going to slink away, now, and find a nice rock to hide under.

(My Christmas reading is Bruce Schneier's wonderful, "Applied
cryptography;" which in turn has led me to the wonderfully big-numbered
and hopelessly OT:
http://www.aleph.se/Trans/Global/Omega/dyson.txt
Everyone who hates thinking about how life can exist at the end of the
universe should go to enormous lengths not to read it.)

..ed
 
C

Christopher Benson-Manica

Daniel Dyer said:
I think there is potentially a distinction between server apps and desktop
apps.

Yes, you're probably right. The bulk of my development experience has
been with desktop applications and so your (snipped) points are well taken.
It is unreasonable to expect the
application to be able to rationally handle a situation that is caused by
its own deficiencies.

That's a succinct summation of the whole situation!
It may be easier said than done, but the only way around this is the
helpful solution suggested by an anonymous project manager: "well, don't
write any bugs then".

A better idea would be "Write better unit tests" :)
 
J

jupiter

Daniel Dyer said:
I think there is potentially a distinction between server apps
and desktop apps.

Huge point.

Catching NPEs reminds me of an old joke about "expect the
unexpected". Yes, it's good to be vigilant, but no, you can't be
that vigilant. If you could be that vigilant then there would be
nothing unexpected.

That's what we need - a platform that offers only the expected
results. Hehe .....
 
D

Daniel Pitts

Frank said:
Thanks. The reason I wanted to catch these exceptions is so I could log
them. It's one thing to have your IDE handle exceptions for you but when
the application is deployed to the field you need to know what exceptions
they get. This method you quoted to set the default uncaught exception
handler is just what I was looking for.

-F

A noble cause indeed. You may also wish to open a JDialog (assuming a
GUI application) which alerts to the user that a problem occured. Just
don't give them too much detail unless they ask for it though.

setDefaultUncaughtExceptionHandler is definetly the way to go in order
to detect uncaught exceptions. It will catch almost all
RuntimeExceptions and Errors. I have had issues catching
OutOfMemoryException, but the JVM is often a in a pretty big fubar
state by that time.
 
A

Andrew Thompson

Daniel said:
Frank wrote: .....
A noble cause indeed. You may also wish to open a JDialog (assuming a
GUI application) which alerts to the user that a problem occured. .....
....I have had issues catching
OutOfMemoryException, but the JVM is often a in a pretty big fubar
state by that time.

There are techniques that can be used even then.
E.G. construct the 'OOM!' UI compononent before
beginning the possible OOM operation, and reserving
a little memory that you immediately release when
an OOM is detected.

Note that I have not personally seen such techniques
to either work or fail - but have been involved in helping
people (via usenet) solve just that problem - they ended
up reporting a workable solution.

(Of course, if the OOM is a mermory leak, we are
probably not expecting it, so the above does not
solve the OP's more general problem.)

Andrew T.
 
J

John Ersatznom

Arne said:
It is usually consider bad practice to present
a stack trace to the end user.

If the application has state in memory that needs to be
persisted it is a very good idea to save the data
before exiting.

If it is a server type application it would be a good idea
to either just terminate one thread and let the other threads
continue serving their clients or at least restart the entire
server app.

I think that in most real world applications you would catch
that kind of exceptions.

I have developed an app along these lines. There's a FooThread class and
a FooThreadFactory, constructors and other methods, and stuff like:

public void run () {
try {
some stuff
} catch (RuntimeException e) {
factory.notifyThreadDeath(this, e);
throw e;
} catch (OutOfMemoryError e) {
app.saveStuff();
factory.shutDown();
factory.notifyThreadDeath(this, e);
throw e;
} catch (Error e) {
factory.notifyThreadDeath(this, e);
throw e;
}
}

Unexpected exceptions are caught and rethrown. Anything other than OOME
results in the thread factory being notified via a
notifyThreadDeath(FooThread, Throwable) method. This logs the stack
trace and decrements a thread count. Elsewhere the factory has a
periodically-called method to interrupt or start threads as need be,
based on a desired number (depending on the number of requests
occurring) and the actual number. (It also keeps a collection of the
actual thread objects, so it can pick some at random to interrupt. The
stuff in the try block involves taking a request off a blocking queue
and handling it in an endless while loop. There's a try that catches
InterruptedExceptions and breaks the while loop, also calling
factory.notifyThreadDeath(this, null).

Upshot: stack traces are logged so things can be debugged. Request
servicing continues, and doesn't even diminish in capacity since the
thread that dies is recreated immediately unless it's no longer needed
anyway. The code that loops the factory's thread-management method
periodically just does so and sleeps, and doesn't do anything that's at
all exception prone itself (it doesn't new anything, for instance,
except thread objects when necessary). OOME causes it to save some data
(mostly caches) and shut down gracefully. (I note that even though the
total megabytage of live objects should remain bounded, it does
eventually slow down and then catch OOME if it runs a long time. Heap
fragmentation?) Restarting the process if it dies somehow is handled
externally. Since it's a network using app, most exceptions are I/O
exceptions that get handled closer to the source, usually by sending the
client an error message and moving on to the next request; they tend to
indicate a problem with connectivity or the client having sent a bad or
malformed request that includes a bogus URL, parse error, or similarly.
Still, the odd wackiness trickles up from time to time. I've had library
code randomly bubble up NPEs and various IndexOutOfBoundsException
flavours, for example, on rare occasions. Lately (since the deployment
environment switched to the Java 6 beta runtime environment) there've
been NPEs coming out of Sun code we can't explain (mainly from one
particular PriorityQueue deep in the bowels of the app -- I found an "in
progress, bug" bug on Sun's site about this one, where someone had it
occur with a comparator not consistent with the objects' equals method,
which is the case in my code also. A quick check of this newsgroup turns
up a complaint of something similar again.) The app recovers from all of
these insults with maybe one in ten thousand requests ending up
incompletely processed. The transaction gets rolled back, but
transactions are pretty much independent of each other, and client
requests that are well-formed but get a "temporary service error"
message are resubmitted by the client after a backoff delay anyway.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top