Skip to main content

Dear Santa - Exceptional Stuff

Posted by brucechapman on August 14, 2007 at 6:22 PM PDT

Dear Santa,

My stack traces seem to have been getting less and less useful recently. Just to make myself perfectly clear, I am not talking about wrapping the sleigh reins around a chimney, which is what you might think of when you hear the words "stack trace".

So here are a couple of things I'd like your seven elves to work on please.

Better messages in JVM thrown Exceptions

First, can the JVM elves please use the information that is available when the JVM throws an exception to create a useful message. For instance, in cases of throwing a NullPointerException, could we please be told the type of the reference that is null, and what it is that can't be done to null.

For example, say you call List.get() on a null reference, wouldn't it be nice to see something like this in the message

Exception in thread "main" java.lang.NullPointerException: ((java.util.List)null).get()

or when accessing an element from a null array

Exception in thread "main" java.lang.NullPointerException: ((String[])null)[]

Those are just suggestions, but having some more information in the message of JVM generated exceptions would make life a little bit more pleasant for me. I am sure I am not the only one who has spent far too long analysing a line of code that throws a NullPointerException trying to work out which reference is null, all the time overlooking the possibility that it was an Integer being used as an array index which was being autounboxed. A meaningful exception message would save an awful lot of wasted time.

As best I can tell this can all be done without actually changing any specs. There are a few related bugs and RFEs in bug parade that address little parts of this, but what I'd really like is for someone to go through the whole JVM Spec, look at each exception that can be thrown by each opcode, and put all the useful information (types and names) available to the JVM into the messages in some consistent notation.

Context Identifiers in StackTraceElements

This suggestion might be a little more controversial. Often the code that is being debugged to find the cause of an Exception is not java code, but some other form that has been converted into a composite data structure and is being "executed" (in loose terms) by java code that someone else wrote for an external library or framework.

Some examples are JSP or JSF pages and scripting language code being run by an interpreter.

What would be really helpful in these cases would be for the stack trace to include a small amount of contextual information associated with key objects in the stack. Wouldn't it be nice if you could see the JSP / JSF EL expression that was being evaluated when an Exception was thrown. Wouldn't it be nice to see the name and source line number of the XML elements that enclosed the element containing that expression? Wouldn't it be nice if you could see the line numbers of the javascript code that was being executed? Wouldn't it be nice if your own classes could add the contents of a String instance field to a stack trace element for specified methods of key classes.

Here's how it might work.

Add a new property to StackTraceElement to hold the context identifier.

Define a marker annotation (say @StackContext).

Use @StackContext to annotate the methods for which you would like the context identifier shown in the stack trace.

For any class with any methods annotated with @StackContext, annotate a single String field with @StackContext to identify the context value.

When a stack trace is being filled in, the JVM would look at each method on the stack, and if it was annotated with @StackContext then the @StackContext field would be accessed, and if non null, then the value of that field would be used to set the context identifier in the corresponding stack trace element.

Printing the stack trace would print the instance identifiers where they were non null.

Other details might include taking a prefix substring if the annotated field's value was too long (say no more than 40 characters), and only filling in the context identifier once for consecutive stack trace elements with the same "this".


Related Topics >>