Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NullPointerException on return new[]

I have a very strange problem with NullPointerException. Code example is as follows:

...
... public String[] getParams(...) {
...   ...
...   ... 
143   return new String[] {
144     getUserFullName(),
145     StringUtil.formatDate(sent),
 .      tiltu,
 .      StringUtil.initCap(user.getName()),
 .      vuosi.toString(),
 .      asiatyyppi[0] + " " + lisatiedot[0],
 .      asiatyyppi[1] + " " + lisatiedot[1],
 .      alaviitteet[0],
152     alaviitteet[1]};
153  }

Now, I have got an issue from production having a stack trace:

java.lang.NullPointerException
    at package.EmailService.getParams(EmailService.java:143)
...

I am unable to produce that kind of stack trace myself. It maybe some environment issue that for some reason line numbers don't match. If I have null references on any variable stack trace points to that specific line but never to line 143.

But what I want to ask is: is it possible to produce NullPointerException at line 143 specifically?

like image 805
M.L. Avatar asked May 11 '15 05:05

M.L.


People also ask

How do I fix NullPointerException?

The NullPointerException can be avoided using checks and preventive techniques like the following: Making sure an object is initialized properly by adding a null check before referencing its methods or properties. Using Apache Commons StringUtils for String operations e.g. using StringUtils.

How do I ignore Java Lang NullPointerException?

Answer: Some of the best practices to avoid NullPointerException are: Use equals() and equalsIgnoreCase() method with String literal instead of using it on the unknown object that can be null. Use valueOf() instead of toString() ; and both return the same result. Use Java annotation @NotNull and @Nullable.

What is NullPointerException when it occurs?

NullPointerException is a runtime exception and it is thrown when the application try to use an object reference which has a null value. For example, using a method on a null reference.

Can we throw NullPointerException Java?

You can also throw a NullPointerException in Java using the throw keyword.


2 Answers

The line number in the stack trace comes from the LineNumberTable attribute in the class file. (See JVM specification)

It would be no problem to output the right line number for a subexpression - all the compiler has to do is to say that from byte-code index x to y, there is a correspondence with source code line z.

But up to and including Java 1.7 there was a bug in the compiler, that was fixed in 1.8:

https://bugs.openjdk.java.net/browse/JDK-7024096

A DESCRIPTION OF THE PROBLEM : linenumbertable in compiled code only has line numbers for starts of statements. When a statement is using method chaining or other "fluent Interface" style API's a single statement can span tens of lines and contain hundreds on method invocations.

Currently an exception throw from within any of these methods will have the linenumber of the first line of the enclosing statement which makes it very hard to debug which method call is having a problem.

linnumbertable should have correct line numbers for every method invocation.

--

BT2:EVALUATION

It seems simple enough to fix this, but its kinda risky at the end of the jdk7 development cycle, targetting to jdk8.

So in 1.7, you would get the wrong reported line number for these kind of subexpressions (if they occurred within the same method though - if you invoked another method in a subexpression, and that other method caused a NullPointerException, you would see it reported there - this is probably why the bug isn't always a big problem)

One way you could work around this is by taking the Java 8 compiler to compile your source code, and use the flags javac -source 1.7 -target 1.7. But it would be better and safer to upgrade your prod environment to 1.8.

like image 172
Erwin Bolwidt Avatar answered Sep 23 '22 15:09

Erwin Bolwidt


Consider your original code which defines a new String array:

return new String[] {
    getUserFullName(),
    StringUtil.formatDate(sent),
    tiltu,
    StringUtil.initCap(user.getName()),
    vuosi.toString(),
    asiatyyppi[0] + " " + lisatiedot[0],
    asiatyyppi[1] + " " + lisatiedot[1],
    alaviitteet[0],
    alaviitteet[1]};
}

If any of the elements of the inline array should trigger a NullPointerException the JVM will interpret the Exception as having occurred on the line where the definition began. In other words, the JVM will view the above code as being the same as:

return new String[] { getUserFullName(), StringUtil.formatDate(sent), tiltu, StringUtil.initCap user.getName()), vuosi.toString(), asiatyyppi[0] + " " + lisatiedot[0], asiatyyppi[1] + " " + lisatiedot[1], alaviitteet[0], alaviitteet[1]}; }

where everything is on one line.

If you really want to handle NullPointerExceptions here, you should define the variables outside the instantiaition.

like image 43
Tim Biegeleisen Avatar answered Sep 21 '22 15:09

Tim Biegeleisen