Question

If I get a NullPointerException in a call like this:

someObject.getSomething().getSomethingElse().
    getAnotherThing().getYetAnotherObject().getValue();

I get a rather useless exception text like:

Exception in thread "main" java.lang.NullPointerException
at package.SomeClass.someMethod(SomeClass.java:12)

I find it rather hard to find out wich call actually returend null, often finding myself refactoring the code to something like this:

Foo ret1 = someObject.getSomething();
Bar ret2 = ret1.getSomethingElse();
Baz ret3 = ret2.getAnotherThing();
Bam ret4 = ret3.getYetAnotherOject();
int ret5 = ret4.getValue();

and then waiting for a more descriptive NullPointerException that tells me which line to look for.

Some of you might argue that concatening getters is bad style and should be avoided anyway, but my Question is: Can I find the bug without changing the code?

Hint: I'm using eclipse and I know what a debugger is, but I can't figuere out how to apply it to the problem.

My conclusion on the answers:
Some answers told me that I should not chain getters one after another, some answers showed my how to debug my code if I disobayed that advice.

I've accepted an answer that taught me excactly when to chain getters:

  • If they cannot return null, chain them as long as you like. No need for checking != null, no need to worry about NullPointerExceptions (be warned that chaining still vialotes the law of demeter, but I can live with that)
  • If they may return null, don't ever, never ever chain them, and perform a check for null values on each one that may return null

This makes any good advice on actual debugging useless.

Was it helpful?

Solution

The answer depends on how you view (the contract of) your getters. If they may return null you should really check the return value each time. If the getter should not return null, the getter should contain a check and throw an exception (IllegalStateException?) instead of returning null, that you promised never to return. The stacktrace will point you to the exact getter. You could even put the unexpected state your getter found in the exception message.

OTHER TIPS

NPE is the most useless Exception in Java, period. It seems to be always lazily implemented and never tells exactly what caused it, even as simple as "class x.y.Z is null" would help a lot in debugging such cases.

Anyway, the only good way I've found to find the NPE thrower in these cases is the following kind of refactoring:

someObject.getSomething()
          .getSomethingElse()
          .getAnotherThing()
          .getYetAnotherObject()
          .getValue();

There you have it, now NPE points to correct line and thus correct method which threw the actual NPE. Not as elegant solution as I'd want it to be, but it works.

In IntelliJ IDEA you can set exceptionbreakpoints. Those breakpoints fire whenever a specified exception is thrown (you can scope this to a package or a class).

That way it should be easy to find the source of your NPE.

I would assume, that you can do something similar in netbeans or eclipse.

EDIT: Here is an explanation on how to add an exceptionbreakpoint in eclipse

If you find yourself often writing:

a.getB().getC().getD().getE();

this is probably a code smell and should be avoided. You can refactor, for example, into a.getE() which calls b.getE() which calls c.getE() which calls d.getE(). (This example may not make sense for your particular use case, but it's one pattern for fixing this code smell.)

See also the Law of Demeter, which says:

  • Your method can call other methods in its class directly
  • Your method can call methods on its own fields directly (but not on the fields' fields)
  • When your method takes parameters, your method can call methods on those parameters directly.
  • When your method creates local objects, that method can call methods on the local objects.

Therefore, one should not have a chain of messages, e.g. a.getB().getC().doSomething(). Following this "law" has many more benefits apart from making NullPointerExceptions easier to debug.

I generally do not chain getters like this where there is more than one nullable getter.

If you're running inside your ide you can just set a breakpoint and use the "evaluate expression" functionality of your ide on each element successively.

But you're going to be scratching your head the moment you get this error message from your production server logs. So best keep max one nullable item per line.

Meanwhile we can dream of groovy's safe navigation operator

Early failure is also an option.

Anywhere in your code that a null value can be returned, consider introducing a check for a null return value.

public Foo getSomething()
{
  Foo result;
  ...
  if (result == null) {
    throw new IllegalStateException("Something is missing");
  }
  return result;
}

Here's how to find the bug, using Eclipse.

First, set a breakpoint on the line:

someObject.getSomething().getSomethingElse().
getAnotherThing().getYetAnotherObject().getValue();

Run the program in debug mode, allow the debugger to switch over to its perspective when the line is hit.

Now, highlight "someObject" and press CTRL+SHIFT+I (or right click and say "inspect").

Is it null? You've found your NPE. Is it non-null? Then highlight someObject.getSomething() (including the parenthesis) and inspect it. Is it null? Etc. Continue down the chain to figure out where your NPE is occurring, without having to change your code.

You may want to refer to this question about avoiding != null.

Basically, if null is a valid response, you have to check for it. If not, assert it (if you can). But whatever you do, try and minimize the cases where null is a valid response for this amongst other reasons.

If you're having to get to the point where you're splitting up the line or doing elaborate debugging to spot the problem, then that's generally God's way of telling you that your code isn't checking for the null early enough.

If you have a method or constructor that takes an object parameter and the object/method in question cannot sensibly deal with that parameter being null, then just check and throw a NullPointerException there and then.

I've seen people invent "coding style" rules to try and get round this problem such as "you're not allowed more than one dot on a line". But this just encourages programming that spots the bug in the wrong place.

Chained expressions like that are a pain to debug for NullPointerExceptions (and most other problems that can occur) so I would advise you to try and avoid it. You have probably heard that enough though and like a previous poster mentioned you can add break points on the actual NullPointerException to see where it occurred.

In eclipse (and most IDEs) you can also use watch expressions to evaluate code running in the debugger. You do this bu selecting the code and use the contet menu to add a new watch.

If you are in control of the method that returns null you could also consider the Null Object pattern if null is a valid value to return.

Place each getter on its own line and debug. Step over (F6) each method to find which call returns null

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top