Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Paths.get() / Path.of() throws NullPointerException on upgrade to Java 16

Tags:

java

path

java-16

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.

like image 962
NaderNader Avatar asked Aug 15 '21 12:08

NaderNader


People also ask

How do I fix NullPointerException in Java?

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 is the reason for NullPointerException?

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.

Should we catch NullPointerException in Java?

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.


2 Answers

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.

like image 91
NaderNader Avatar answered Oct 20 '22 04:10

NaderNader


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:

  1. Paths.get calls Path.of internally. (Paths.java)

     public static Path get(String first, String... more) {
         return Path.of(first, more);
     }
    
  2. Path.of code . (Path.java)

    public static Path of(String first, String... more) {
     return FileSystems.getDefault().getPath(first, more);
    }
    
  3. Then as per the file system it calls the suitable getPath method.
    a. WindowsFileSystem
    b. UnixFileSystem

  4. In that method we have a check which confirms that first parameter/path is not null

    Objects.requireNonNull(first);
    
  5. 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;
    }
    
like image 44
Tris Avatar answered Oct 20 '22 03:10

Tris