This question already has answers here:
Gracefully avoiding NullPointerException in Java
(9 answers)
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 8 years ago.
So working through a few Java based web applications, I realized one common thing in pretty much most of the web applications. Most of them tend to run fine until you meet face to face with a Null Pointer Exception. Below is one of the methods that is returning an error:
public Map getWebSiteObjects(String path, LightWeightNode root, Integer versionId, Site site) {
Map webSiteObjects = new HashMap();
// refresh site
site = (Site)getObject(Site.class, site.getId());
webSiteObjects.put("site", site); ...... /* Dont worry about the rest */
Scenario: This method generates a tree on my application, however, it's giving a null pointer exception at runtime:
2014-10-09 12:00:18,674 ERROR org.springframework.web.servlet.DispatcherServlet - Could not complete request
java.lang.NullPointerException at com.bsdeurope.xmlcms.service.impl.TreeManagerImpl.getWebSiteObjects(TreeManagerImpl.java:159)
Now I'm quite new with some Java principals(fundamentals) and my idea to solve this was to initialize the 4 variables passed in the method therefore have:
path = null;
root =null;
versionId = null;
site = null;
before any instructions within the getWebSiteObjects method. Now I know this might not be the only solution but my question is:
1) What is good practice in terms of preventing Java Null Pointer Exceptions?
2) If there is a procedure how would you go about doing it?
Usually when working with a lot of classes especially applications with code that is badly written you end up hitting your head against the wall when you get tons of null pointer exceptions left, right and center.
There are two schools of thought on this.
One school, says test for the null and do something to "make good". For example, replace it with something else, ignore it, write a log message, and so on.
The other school is that an unexpected null is a BUG, and the correct thing to do is to allow the NullPointerException to be thrown. Then you allow the NPE to propagate up and (ideally) cause the program to crash ... or better still, fail gracefully after logging the NPE stacktrace in the application's log files.
Then it is up to the programmer to use the information in the stacktrace (and "those little grey cells" to quote a well-known fictional Belgian detective) to figure out where the unexpected null came from, and fix the root cause of the problem. Typically this entails finding the field or array element or whatever that was incorrectly initialized, of the get call that returns a null to indicate (soft) failure, or whatever. This fix may involve testing for null, or it may involve initializing something, or passing something, or correcting some logic, or adding the null test earlier in the program.
IMO, the practice of adding defensive tests for null all over the place is a bad idea. It tends to replace one kind of bug (an NPE) with another kind that is often harder to track down.
So my answers would be:
1) What is good practice in terms of preventing Java Null Pointer Exceptions?
Good practice is to not avoid the NPEs. Instead let them happen, and find / fix what is introducing the spurious null values.
2) If there is a procedure how would you go about doing it?
No there isn't. Certainly there is no procedure that >>I<< would use.
The only thing I would do would be to try to make my code throw the NPE earlier, so that the null doesn't get passed a long way from its original source. (That tends to make it easier to find and fix the root cause of the problem.)
A null check is usually enough.
// refresh site
if(site!=null){
site = (Site)getObject(Site.class, site.getId());
webSiteObjects.put("site", site); ...... /* Dont worry about the rest */
}else{
// Print an error message, or do the error handling here...
}
Note that, NullPointerException will only come when your expression evaluates to null.someFunction() . In this example, site.getId(). So null check for only site!=null is enough. If you have more object.someFunction() then you may want to do something like
if(obj1!=null && obj2!=null){
// Safe to call
obj1.function();
obj2.function();
}
For you Program here is a simple null check:
public Map getWebSiteObjects(String path, LightWeightNode root, Integer versionId, Site site) {
Map webSiteObjects = new HashMap();
if(null!=Site){
// refresh site
site = (Site)getObject(Site.class, site.getId());
webSiteObjects.put("site", site); ...... /* Dont worry about the rest */
}
//Similarly while using other arguments do similar null check
(if null!=path){
/*
Your code here...
*/
}
}
For best practices to avoid NPE check this link: NPE practices
you can put all your business logic of any method in try block
try{
Map webSiteObjects = new HashMap();
// refresh site
site = (Site)getObject(Site.class, site.getId());
webSiteObjects.put("site", site); ...... /* Dont worry about the rest */
}catch(NullPointerException e){
// error occured
e.printStackTrace();
}
Related
This question already has answers here:
When is it OK to catch NullPointerException?
(10 answers)
Closed 3 years ago.
Bear with me, as I've read a bit on this and I'm still not sure if I'm thinking about this correctly, but I want to understand this fully...
I've recently found myself in a debate that surrounds a pragmatic approach to code, whereby the feedback I've been given is (I think) a misrepresentation of general Software Engineering advice.
So consider you have a method that handles an input - let's say you take in a String and format in a particular way (assume it's not a way that any existing Java until provides). The method could throw a NPE if null is passed in, because that shouldn't happen.
I didn't add in any NPE handling like the Apache Commons library for StringUtils has, where when you pass in null it provides back an empty string because, in the context of the method, a null shouldn't be provided. I wanted to leave it up to the implementation to determine how to handle this.
The logic for this, by me, is that you wouldn't necessarily want this null value to just be swallowed as normal, but might want to catch this and rethrow the occurance as another exception to explain "this shouldn't have happened" - say, if it was for a step that was considered mandatory.
A colleagues said that "catching NPEs is considered bad practice", but further research on this suggests this is only the case where you're ignoring the NPE (or swallowing it).
To my mind, that's what
if(var = null) { return ""; }
(for example) is doing, whilst actually handling the null as an exception...
try {
myStringMethod( somevar );
}
catch ( final NullPointerException e )
{
Throw new MySpecificException( e );
}
... Is an effective way of handling a mandatory value that shouldn't be null.
In the way it was put across, it seems to suggest a NPE should never be seen - which I agree with, but surely "dealing with it" by somewhat ignoring the cause is actually the wrong way?
NullPointerException is (almost) always a bug. Either a method accept null as an argument, in which case it should never throw NPE. Or it doesn't accept null, in which case the caller is responsible for not passing it.
Catching NullPointerException is (almost) never the solution.
After checking the JavaDocs for a method I was thinking of using, requiredNonNull, I stumbled across the first one with the single parameter (T obj).
However what is the actual purpose of this particular method with this signature? All it simply does is throw and NPE which I'm somewhat positive (as a I may be missing something obvious here) would be thrown anyway.
Throws:
NullPointerException - if obj is null
The latter actually makes sense in terms of debugging certain code, as the doc also states, it's primarily designed for parameter validation
public static <T> T requireNonNull(T obj,String message)
Checks that the specified object reference is not null and throws a customized NullPointerException if it is.
Therefore I can print specific information along with the NPE to make debugging a hell of a lot easier.
With this in mind I highly doubt I would come across a situation where I'd rather just use the former instead. Please do enlighten me.
tl;dr - Why would you ever use the overload which doesn't take a message.
A good principle when writing software is to catch errors as early as possible. The quicker you notice, for example, a bad value such as null being passed to a method, the easier it is to find out the cause and fix the problem.
If you pass null to a method that is not supposed to receive null, a NullPointerException will probably happen somewhere, as you already noticed. However, the exception might not happen until a few methods further down, and when it happens somewhere deep down, it will be more difficult to find the exact source of the error.
So, it's better when methods check their arguments up front and throw an exception as soon as they find an invalid value such as null.
edit - About the one-parameter version: even though you won't provide an error message, checking arguments and throwing an exception early will be more useful than letting the null pass down until an exception happens somewhere deeper down. The stack trace will point to the line where you used Objects.requireNonNull(...) and it should be obvious to you as a developer that that means you're not supposed to pass null. When you let a NullPointerException happen implicitly you don't know if the original programmer had the intent that the variable should not be null.
It is a utility method. Just a shortcut! (shortcut designers have their ways of doing their shortcut style).
Why throwing in the first place?
Security and Debugging.
Security: to not allow any illegal value in a sensitive place. (makes inner algorithm more sure about what are they doing and what are they having).
Debugging: for the program to die fast when something unexpected happens.
I'm pretty new to Java so bear with me. Basically I have a class named "returnPages" that returns the parent page that you are currently on. The problem is when you're at the highest level or the root it throws an error, logically because the root doesn't have a parent it will throw a null pointer exception. How would I prevent an error being thrown when your at the root? I thought the below code would work but I'm simply getting a null pointer exception were I start my conditional. Note: I'm trying to run this in the JSP, modifying the returnPages class will result in multiple conflicts across the site. Also the returnPages class takes two arguments the first is parent page followed by the current page your on.
Page rootPage = properties.get("rootPage", "");
if(returnPages.getPath(rootPage, currentPage) != null){
List<Page> trail = returnPages.getPath(rootPage, currentPage);
} else {
//show something here
}
Any help is greatly appreciated!
You can use
return Collections.emptyList<Page>();
Or simply
return new LinkedList<Page>();
The first option returns an immutable list, so attempting to add anything to that list will fail with an exception. You use less memory though and ensure the list is not modified, which is sometimes a good thing.
Edit: why are you doing the lookup twice?
List<Page> trail = returnPages.getPath(rootPage, currentPage);
if (trail == null) {
trail = Collections.emptyList<Page>();
}
If returnPages.getPath(rootPage, currentPage) is throwing an NPE yo uhave to deal with it. you cannot check if it returns null or not
try {
List<Page> trail = returnPages.getPath(rootPage, currentPage);
} catch (NullPointerException e){
//show something here
}
There are great debates about unchecked and checked exceptions in java. NullPointer is an unchecked exception so usually means programmer error. Some people say you should not catch them. What you could do instead of returning null is return an empty list
Edit after comment:
A null pointer is thrown when you try and access something on a null object. (It's really a NullReferenceException but again there are many debates on that)
What you are doing is checking if the returned object from the method is null. Inside the returnPages.getPath(rootPage, currentPage) it is throwing a NullPointerException - not returning it. (in effect returning nothing because of this error condition and throwing the exception). When to throw an exception? gives details on this. In older languages error codes are returned so you could do a check like you are. Java has an exception handling framework which is why the author of getPath has decided to throw an exception rather than return null
You should paste the stacktrace of that NullPointerException because it is not the same thing if that exception comes from getPath() or if it comes from the condition if (returnPages.getPath(....
This might be the same issue as in your earlier question.
UPDATE: (Moving my comment to this answer.)
This is an old issue (see the question). The sentence "modifying the returnPages class will result in multiple conflicts across the site" doesn't make sense at all since neither the method interface nor its functionality has changed.
I’m from a .NET background and now dabbling in Java.
Currently, I’m having big problems designing an API defensively against faulty input. Let’s say I’ve got the following code (close enough):
public void setTokens(Node node, int newTokens) {
tokens.put(node, newTokens);
}
However, this code can fail for two reasons:
User passes a null node.
User passes an invalid node, i.e. one not contained in the graph.
In .NET, I would throw an ArgumentNullException (rather than a NullReferenceException!) or an ArgumentException respectively, passing the name of the offending argument (node) as a string argument.
Java doesn’t seem to have equivalent exceptions. I realize that I could be more specific and just throw whatever exception comes closest to describing the situation, or even writing my own exception class for the specific situation.
Is this the best practice? Or are there general-purpose classes similar to ArgumentException in .NET?
Does it even make sense to check against null in this case? The code will fail anyway and the exception’s stack trace will contain the above method call. Checking against null seems redundant and excessive. Granted, the stack trace will be slightly cleaner (since its target is the above method, rather than an internal check in the HashMap implementation of the JRE). But this must be offset against the cost of an additional if statement, which, furthermore, should never occur anyway – after all, passing null to the above method isn’t an expected situation, it’s a rather stupid bug. Expecting it is downright paranoid – and it will fail with the same exception even if I don’t check for it.
[As has been pointed out in the comments, HashMap.put actually allows null values for the key. So a check against null wouldn’t necessarily be redundant here.]
The standard Java exception is IllegalArgumentException. Some will throw NullPointerException if the argument is null, but for me NPE has that "someone screwed up" connotation, and you don't want clients of your API to think you don't know what you're doing.
For public APIs, check the arguments and fail early and cleanly. The time/cost barely matters.
Different groups have different standards.
Firstly, I assume you know the difference between RuntimeExceptions (unchecked) and normal Exceptions (checked), if not then see this question and the answers. If you write your own exception you can force it to be caught, whereas both NullPointerException and IllegalArgumentException are RuntimeExceptions which are frowned on in some circles.
Secondly, as with you, groups I've worked with but don't actively use asserts, but if your team (or consumer of the API) has decided it will use asserts, then assert sounds like precisely the correct mechanism.
If I was you I would use NullPointerException. The reason for this is precedent. Take an example Java API from Sun, for example java.util.TreeSet. This uses NPEs for precisely this sort of situation, and while it does look like your code just used a null, it is entirely appropriate.
As others have said IllegalArgumentException is an option, but I think NullPointerException is more communicative.
If this API is designed to be used by outside companies/teams I would stick with NullPointerException, but make sure it is declared in the javadoc. If it is for internal use then you might decide that adding your own Exception heirarchy is worthwhile, but personally I find that APIs which add huge exception heirarchies, which are only going to be printStackTrace()d or logged are just a waste of effort.
At the end of the day the main thing is that your code communicates clearly. A local exception heirarchy is like local jargon - it adds information for insiders but can baffle outsiders.
As regards checking against null I would argue it does make sense. Firstly, it allows you to add a message about what was null (ie node or tokens) when you construct the exception which would be helpful. Secondly, in future you might use a Map implementation which allows null, and then you would lose the error check. The cost is almost nothing, so unless a profiler says it is an inner loop problem I wouldn't worry about it.
In Java you would normally throw an IllegalArgumentException
If you want a guide about how to write good Java code, I can highly recommend the book Effective Java by Joshua Bloch.
It sounds like this might be an appropriate use for an assert:
public void setTokens(Node node, int newTokens) {
assert node != null;
tokens.put(node, newTokens);
}
Your approach depends entirely on what contract your function offers to callers - is it a precondition that node is not null?
If it is then you should throw an exception if node is null, since it is a contract violation. If it isnt then your function should silently handle the null Node and respond appropriately.
I think a lot depends on the contract of the method and how well the caller is known.
At some point in the process the caller could take action to validate the node before calling your method. If you know the caller and know that these nodes are always validated then i think it is ok to assume you'll get good data. Essentially responsibility is on the caller.
However if you are, for example, providing a third party library that is distributed then you need to validate the node for nulls, etcs...
An illegalArugementException is the java standard but is also a RunTimeException. So if you want to force the caller to handle the exception then you need to provided a check exception, probably a custom one you create.
Personally I'd like NullPointerExceptions to ONLY happen by accident, so something else must be used to indicate that an illegal argument value was passed. IllegalArgumentException is fine for this.
if (arg1 == null) {
throw new IllegalArgumentException("arg1 == null");
}
This should be sufficient to both those reading the code, but also the poor soul who gets a support call at 3 in the morning.
(and, ALWAYS provide an explanatory text for your exceptions, you will appreciate them some sad day)
like the other : java.lang.IllegalArgumentException.
About checking null Node, what about checking bad input at the Node creation ?
I don't have to please anybody, so what I do now as canonical code is
void method(String s)
if((s != null) && (s instanceof String) && (s.length() > 0x0000))
{
which gets me a lot of sleep.
Others will disagree.
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 which call actually returned 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 concatenating 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 figuer 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 disobeyed that advice.
I've accepted an answer that taught me exactly 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 violates 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.
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.
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.
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