listFiles() returns null when it shouldn't. It used to work properly until recently and hasn't been modified

27.3k views Asked by At
public static void main(String[] args) throws InterruptedException {
    // TODO Auto-generated method stub
    while(true)
    {
        ArrayList<File> wallpapers = new ArrayList<File>();
        File dir = new File("C:/Windows/System32/oobe/info/backgrounds/");
        if(dir.listFiles() == null)
            System.out.println("Empty");
        for(File img : dir.listFiles())
        {
            if(img.getName().endsWith(".jpg") && img.getName() != "backgroundDefault.jpg")
                wallpapers.add(img);
        }
        File current = new File("C:/Windows/System32/oobe/info/backgrounds/backgroundDefault.jpg");
        int i = 1;
        for(File img : wallpapers)
        {
            File f = new File("C:/Windows/System32/oobe/info/backgrounds/"+ i++ +".jpg");
            current.renameTo(f);
            File file = new File("C:/Windows/System32/oobe/info/backgrounds/backgroundDefault.jpg");
            img.renameTo(file);
            Thread.sleep(60000);
        }

    }
}   }
}

This code changes the background image of the Windows Log In screen every minute. listFiles() returns null for dir and I get a NullPointerException on for(File img : dir.listFiles()). I thought there may be a problem with file rights so I tried to change the file path to a directory I have on my Desktop and it works fine. So I'm assuming I can't access system files because my program doesn't have enough rights. Let me also precise that this code used to work fine until recently. It hasn't been modified. I just found out that my Log In Wallpaper doesn't change anymore. Even when the program did work I couldn't modify the file name when I launched the program through Eclipse but I would export it as .jar and schedule it with Task Scheduler with highest privileges to give it admin rights and it worked without any problems until recently. I also tried ignoring the errors thinking they were related to access rights and tried to launch my executable jar with highest privileges through Task Scheduler and also using a batch file. I even tried launching the jar through a cmd I opened with Administrator Rights to no avail it still says NullPointerException in the cmd. I'm kind of lost and would appreciate any help.

4

There are 4 answers

2
piet.t On BEST ANSWER

On Windows 7 (and later) the process will have to run with elevated privileges to write to C:/Windows and similar directories. But if that was the problem it would result in a different error message.

What I suspect: When running a 32-bit JVM under 64-bit Windows new File("C:/Windows/System32") will point to C:\Windows\SysWOW64 and there is no info-Folder under C:\Windows\SysWOW64\oobe

As a test:

public static void main(String[] args) {
    File sysdir = new File("C:/Windows/System32/oobe/info");
    for(File file:sysdir.listFiles()) {
        System.out.println(file.getName());
    }
}

runs fine with 64-bit-JRE and throws NullPointerException under 32-bit-JRE on Windows 7 64-bit.

So perhaps you or another application recently installed a 32-bit-jre or changed your path to point to a 32-bit-jre and thus broke your application.

5
Octoshape On

If you get a NullPointerException on the line for(File img : dir.listFiles()) that means that the variable dir is null and you can't call listFiles() on it. Have you tried debugging it and see if maybe the directory path has changed or that dir is in fact set properly?

2
user207421 On

listFiles() returns null for dir and I get a NullPointerException on for(File img : dir.listFiles()).

It "returns null if this abstract pathname does not denote a directory, or if an I/O error occurs". So either it isn't a directory, or an I/O error occurred.

You need to code defensively against this possibility rather than just contra-factually assert that "it shouldn't". It did, and it can.

Maybe you should remove the trailing /.

0
Paul Samsotha On

Don't compare strings with ==

if(img.getName().endsWith(".jpg") && img.getName() != "backgroundDefault.jpg")

Use equals

if(img.getName().endsWith(".jpg") && !(img.getName()).equals("backgroundDefault.jpg"))