Java: list files returns null on external storage on MacOS

Viewed 407

When I try to list the content of a folder on an external storage with file.list(), the method always returns null. The doc does not really help. It says:

Returns null if this abstract pathname does not denote a directory, or if an I/O error occurs.

In my case, the abstract pathname does denote a directory (according to Java itself) and the permissions seems fine.

Any help would be appreciated. So far, I found solution only for Android. I am using macOS Big Sur 11.4 (I don't have a linux or a windows machine to test) with JDK 15.

import java.io.File;
import java.util.Arrays;

class Main
{

    public static void main(String[] args)
    {
        var path = "/Volumes/MyStorage";
        var file = new File(path);

        System.out.println("Username: " + System.getProperty("user.name"));
        System.out.println("File exists: " + file.exists());
        System.out.println("File is a directory: " + file.isDirectory());
        System.out.println("List of files: " + Arrays.toString(file.list()));
    }

}

Output:

Username: username
File exists: true
File is a directory: true
List of files: null

The permissions seems fine:

$ ls -la /Volumes/
total 0
drwxr-xr-x   4 root      wheel  128 May 29 21:08 .
drwxr-xr-x  20 root      wheel  640 Jan  1  2020 ..
drwxrwxr-x  13 username  staff  510 May 29 20:52 MyStorage
lrwxr-xr-x   1 root      wheel    1 May 26 10:15 Macintosh HD -> /

As username, I have access to the entire structure of MyStorage. I can list the content of the disk using ls /Volumes/MyStorage.

Edit:

As requested in comment, here is the stack trace of the error I get using Files.list(Path.of(path)):

java.nio.file.FileSystemException: /Volumes/MyStorage: Operation not permitted
    at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:100)
    at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
    at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
    at java.base/sun.nio.fs.UnixFileSystemProvider.newDirectoryStream(UnixFileSystemProvider.java:411)
    at java.base/java.nio.file.Files.newDirectoryStream(Files.java:476)
    at java.base/java.nio.file.Files.list(Files.java:3765)
    at Main.main(Main.java:22)

Which is very puzzling considering the permissions on the folder look fine. Also, other languages have no problem listing the folder (C, Python, and probably others). I tried running the working python script as a subprocess in Java, but it does not work (folder appears empty).

Edit 2:

I have been running the java app within NetBeans so far. But if I run the java app via the shell (java -jar myapp.jar), then it works:

$ java -jar TestApplication.jar
Username: username
File exists: true
File is a directory: true
List of files: [.DocumentRevisions-V100, .DS_Store, .fseventsd, .Spotlight-V100, .TemporaryItems, .Trashes, private, work]

Is it possible for NetBeans (and only netbeans?) to not have the permission to list a folder?

Edit 3:

Narrowing down the problem thanks to dan1st. When I pack the app with packr and run the .app file, then macOS asks me to give my authorization to list removable storage (the black rectangle hides the name of my app): macOS asking for permission to list removable storage contente

If I click "Ok", then it works as expected. Unfortunately, We cannot add these authorization for NetBeans manually. Perhaps this is a problem for "Ask Different"?

1 Answers

Works for me on MacOS Monterey: (Thanks @Teddy)

Go to Security and Privacy settings,
-> Privacy
-> scroll down to "Files and Folders" permission
-> you may have to click the "lock" to permit changes
-> add Java
-> tick the "Downloads" box if you like

After this change, running my java app from the terminal, works.

Related