1

If you need any other information please let me know.

Short Version:

This line of code causes a NullPointerException when tested with jUnit 4.12:

File[] files = new File(searchPath).listFiles();

Long version:

First of all, this is the enviroment:

  • OS: Win7 Pro (Netbeans runs as Admin)
  • IDE: Netbeans 8.0.2
  • Build automation tool: Gradle
  • Java: JDK 1.8
  • Test-Framework: jUnit 4.12

The exception only occurs when i run jUnit-tests. When i build it without any tests, everything works fine and the function listFiles() from File[] files = new File(searchPath).listFiles() doesn't return null.

gradle clean & gradle build -x test & gradle rest:jettyRun 2> test.txt

This is the problem-function, called in the constructor of my class:

/**
 * Scans for JSON files on given path
 * @param searchPath full path given
 * @return String[] with the full paths and names of found files
 */
private String[] scanForJsons(String searchPath){
    System.out.println("search path "+searchPath); // shows D:\..\core\files

    File[] files = new File(searchPath).listFiles(); // problem line, allways returns null

    System.out.print(((files!=null)?"Not null" : "Null"));
    System.out.println("files.length: "+files.length);
    String[] stringArray = new String[files.length];

    for(int i = 0; i < files.length; i++){
        String path = files[i].getName();
        if (path.endsWith(".json")) {
            path = path.substring(0, path.length() - 5);
        }
        stringArray[i] = path;
    }
    return stringArray;
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Now it's not clear whether the problematic line *returns* null or throws an exception. Your text says one thing, the comment says another. Also, please provide the unit test in question. – Jon Skeet Sep 25 '15 at 13:43

2 Answers2

1

The documentation for File.listFiles() includes:

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

So it looks like that's what's happening. A path of d:\..\core\files doesn't look like a valid pathname to me... how can you expect a directory to be the parent of a root directory?

You need to change your test to provide a valid path - and quite possibly change your method to cope with listFiles() potentially returning null.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Actually it's a valid pathname. I just shortened it in my comments with .. because there was my real name in it. [Edit] That is the full path: D:\OneDrive\MyName\Projekte\Java\REST\Projekt_Abgabe\Rechteverwalltung\Data\core\files – ZeugeDerUnity Sep 25 '15 at 13:47
  • @ZeugeDerUnity: Well that's not terribly helpful, is it? I suggest you try logging `File.exists(searchPath)` and `File.isDirectory(searchPath)`... I still expect the problem is due to the path being inappropriate in some way. – Jon Skeet Sep 25 '15 at 13:48
  • I addet the following line on top of the mentioned function: `File directory = new File(searchPath); System.out.println("Is directory?: " + (directory.isDirectory()?"Yes":"No"));` When i run the jUnit-Test: **Is directory?: No** When i build it without the tests and run it with jettyRun: **Is directory?: Yes** – ZeugeDerUnity Sep 25 '15 at 14:01
  • Well what is the path? If it's a relative path, it may well be a matter of where the tests run from... Try printing out `directory.getCanonicalPath()`. – Jon Skeet Sep 25 '15 at 14:05
  • Ok, it says: D:\OneDrive\MyName\Projekte\Java\REST\Projekt_Abgabe\Rechteverwalltung\Data\core‌​\files (with jUnit and jettyRun) – ZeugeDerUnity Sep 25 '15 at 14:11
  • @ZeugeDerUnity: So have you tried running the tests from the command line JUnit test runner, without getting Gradle and jettyRun involved? You basically need to narrow it down - although unit tests hitting the file system is *usually* a bad idea anyway. – Jon Skeet Sep 25 '15 at 14:12
  • No i didn't know that i could run test from console, i'll look that up and try immediately. Actually it's my first time using this framework. I did some experiments by myself and figured out, that there is no problem for the jUnit-tests to use `File[] files = new File(searchPath).listFiles();` . The problem occurs, when the test tries to use the class with *scanForJsons* in the constructor. I'll try to get a StackTrace. – ZeugeDerUnity Sep 25 '15 at 14:56
1

As in the description of java.io.File, java.nio.file should be used to overcome limitations from java.io.File.

After i reworked the whole function and migrated from java.io.File and Strings to java.nio.file and Path it works fine.

The code was found at Read all files in a folder.

private List<Path> scanForJsons(Path pathScanned){
    List<Path> pathList = new ArrayList<>();
    try {
            Files.walk(pathScanned).forEach(filePath -> {
            if (Files.isRegularFile(filePath)) {
                pathList.add(filePath);
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
    }
    return pathList;
}

Even if i don't need it anymore i wrote the function to get just the filenames without the file extension:

//Get a list of the filenames without the filename extension
private List<String> getRawNamesOfFiles(String filenameExtension){
    List<String> fileNames = new ArrayList<String>();
    try {
        Files.walk(Paths.get("").toAbsolutePath().getParent()).forEach(filePath -> {
            if (Files.isRegularFile(filePath)) {
                String fileName = getRawNameOfFile(filePath, filenameExtension);
                if(fileName != null){
                    fileNames.add(fileName);
                }
            }
        });
    } catch (IOException e) {
        e.printStackTrace();
    }
    return fileNames;
}

// removes the filename extension 
// checks if the file extension of the path fits the wanted filename extension, returns null if it doesn't fit
private String checkAndEditTheName(Path path, String wantedFilenameExtension){
    int cutLength = wantedFilenameExtension.length() + (wantedFilenameExtension.startsWith(".")?0:1);
    String pathEnd = path.getFileName().toString();
    if(pathEnd != null && pathEnd.endsWith(wantedFilenameExtension)){ //search for a specific filename extension
        pathEnd = pathEnd.substring(0, pathEnd.length() - cutLength); // remove the filename extension and the point
        return pathEnd;
    }
    return null;
}
Community
  • 1
  • 1