Issue with Objects.nonNull() behavior

Tags:



Using Java 11. Noticing a strange behavior with very simple functionality. In the following code, if the expiration date is not null, only then it should try to extract the sql.Timestamp from the given Instant field.

preparedStatement.setTimestamp(expirationDateParameterIndex,
                            Objects.nonNull(memberReward.getExpirationDate())
                            ? Timestamp.from(memberReward.getExpirationDate())
                            : null);

Problem is that even though the expiration date is set to null, Timestamp.from(..) is called and throwing NullPointerException.

java.lang.NullPointerException: null
at java.sql/java.sql.Timestamp.from(Timestamp.java:545)

The issue is not reproducible outside the project.

Here are the debugging screenshots: enter image description here


enter image description here


enter image description here

Answer

Well, your debug screenshot is clear: null was passed to Timestamp.from(), which means memberReward.getExpirationDate() is null.

That’s weird, because right before that, you check for that condition! Thus, we get to these explanations, all quite exotic:

  • getExpirationDate() is non-stable: It returns different values every time. Imagine it was implemented as follows: return random.coinFlip() == HEADS ? null : someDateObj; – then this can happen. One way to fix this is to call it once, save to a local variable, and carry on with that.
  • expirationDate is not immutable, and some other thread is setting the value in between your check and your read. This is unlikely, but technically possible, and suggests you need a serious rewrite of it all, having such casual shared mutable state between threads means this is just one of a ton of race conditions.
  • The code you’re seeing is not the code that is running.
  • You’re getting to Timestamp.from from different code than what you pasted.
  • That is not the Objects of java.util, and the nonNull method on it, is broken.

These all sound exotic, but it must be one of these things.



Source: stackoverflow