When upgrading from Java 15 to Java 16, some of my unit tests began failing due to a null pointer exception. The issue was caused by a null value being passed to the Paths.get() api. What changed in Java 16 to make this an error?
I am using OpenJDK version 16.0.2 and am running on macos.
In Java, the java. lang. NullPointerException is thrown when a reference variable is accessed (or de-referenced) and is not pointing to any object. This error can be resolved by using a try-catch block or an if-else condition to check if a reference variable is null before dereferencing it.
What Causes NullPointerException. The NullPointerException occurs due to a situation in application code where an uninitialized object is attempted to be accessed or modified. Essentially, this means the object reference does not point anywhere and has a null value.
It is generally a bad practice to catch NullPointerException. Programmers typically catch NullPointerException under three circumstances: The program contains a null pointer dereference. Catching the resulting exception was easier than fixing the underlying problem.
As of Java 16, the implementation of Paths.get(), which internally calls Path.of(), now explicitly requires the 'first' path element to be non-null.
This is an implementation change from Java 15, but is consistent with the specification. The package javadoc for java.nio.files states "Unless otherwise noted, passing a null argument to a constructor or method of any class or interface in this package will cause a NullPointerException to be thrown."
This implementation change can be considered and improvement because it will no longer hide the string value "null" appearing in file system paths, which is likely not the desired outcome.
In this case, a unit test was breaking because of an improperly initialized mock object.
It is an expected exception where first argument of Paths.get()
or Path.of()
is null
. There was a known bug which is fixed as part of Java 16 release.
Bug: link
This is mentioned in the Jdk 16 release notes as well. link
(fs) NullPointerException Not Thrown When First Argument to Path.of or Paths.get Is null (JDK-8254876)
core-libs/java.nio The var args form of Path.of() and Paths.get() method are changed in this release to throw NullPointerException consistently when the first parameter is null. Historically these methods missed a null check on the first parameter when invoked with more than one parameter.
Code flow:
Paths.get
calls Path.of
internally. (Paths.java)
public static Path get(String first, String... more) {
return Path.of(first, more);
}
Path.of
code . (Path.java)
public static Path of(String first, String... more) {
return FileSystems.getDefault().getPath(first, more);
}
Then as per the file system it calls the suitable getPath
method.
a. WindowsFileSystem
b. UnixFileSystem
In that method we have a check which confirms that first parameter/path is not null
Objects.requireNonNull(first);
When the first parameter is null
then NPE is thrown. (Objects.java)
public static <T> T requireNonNull(T obj, String message) {
if (obj == null)
throw new NullPointerException(message);
return obj;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With