JDK-6753652 : JFileChooser can throw NPE at various times if a directory or file is deleted
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6u10
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2008-09-29
  • Updated: 2011-02-16
  • Resolved: 2010-06-26
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_10-rc"
Java(TM) SE Runtime Environment (build 1.6.0_10-rc-b28)
Java HotSpot(TM) Client VM (build 11.0-b15, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
Various JFileChooser operations can throw a NullPointerException if a directory (or file, I assume) is deleted at the right time. The problem is that all methods in FileSystemView assume that FileSystemView.getShellFolder(File) returns non-null. But on Windows (at least), it will return null if the file doesn't exist. It is assumed by the code that all paths to getShellFolder(File) test the file for existence first, but even if true, that is insufficient. The file might exist during the test but no longer exist at the necessary time. FileSystemView needs to be reworked to remedy this problem. As far as I know, this bug exists in all recent versions of Java. The bug happens rarely "in real life", but we get occasional "crash reports" from users showing that it does sometimes happen, and if someone navigates a file chooser to a directory where files or subdirectories are being created and destroyed frequently, it would be quite likely.

In the stack dump from my test, you could say that the exception happens because the file loading thread does not check the directory for existence before calling FileSystemView.getFiles(), but that is not the root problem. Adding such a test might drastically decrease the chances of encountering the bug for this particular test case, but as long as FileSystemView assumes that FileSystemView.getShellFolder(File) returns non-null, there is always some chance of it happening.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Change indicated filename in code if necessary.
Compile and run.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Expect no output.

ACTUAL -
Occasionally get internal error message from caught FileNotFoundException in FileSystemView.getShellFolder(File), followed by uncaught NullPointerException.


ERROR MESSAGES/STACK TRACES THAT OCCUR :
FileSystemView.getShellFolder: f=C:\jfctest14\jfctest14
java.io.FileNotFoundException
	at sun.awt.shell.ShellFolder.getShellFolder(ShellFolder.java:208)
	at javax.swing.filechooser.FileSystemView.getShellFolder(FileSystemView.java:507)
	at javax.swing.filechooser.FileSystemView.getFiles(FileSystemView.java:431)
	at javax.swing.plaf.basic.BasicDirectoryModel$LoadFilesThread$1.call(BasicDirectoryModel.java:225)
	at javax.swing.plaf.basic.BasicDirectoryModel$LoadFilesThread$1.call(BasicDirectoryModel.java:221)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
	at java.util.concurrent.FutureTask.run(FutureTask.java:138)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at sun.awt.shell.Win32ShellFolderManager2$ComInvoker$3.run(Win32ShellFolderManager2.java:458)
	at java.lang.Thread.run(Thread.java:619)
Exception in thread "Basic L&F File Loading Thread" java.lang.NullPointerException
	at javax.swing.filechooser.FileSystemView.getFiles(FileSystemView.java:434)
	at javax.swing.plaf.basic.BasicDirectoryModel$LoadFilesThread$1.call(BasicDirectoryModel.java:225)
	at javax.swing.plaf.basic.BasicDirectoryModel$LoadFilesThread$1.call(BasicDirectoryModel.java:221)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
	at java.util.concurrent.FutureTask.run(FutureTask.java:138)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at sun.awt.shell.Win32ShellFolderManager2$ComInvoker$3.run(Win32ShellFolderManager2.java:458)
	at java.lang.Thread.run(Thread.java:619)


REPRODUCIBILITY :
This bug can be reproduced occasionally.

---------- BEGIN SOURCE ----------
import javax.swing.*;
import java.io.File;

public class JFileChooserBug14 {
   private static JFileChooser jfc;
 
   public static void main(String[] args) {
      SwingUtilities.invokeLater(
         new Runnable() {
             public void run() {
               start();
            }
         });
      // Change this to something useful if not on Windows.
      final File f = new File("C:\\jfctest14\\jfctest14");
      while (true) {
         SwingUtilities.invokeLater(
            new Runnable() {
                public void run() {
                  if (jfc == null) {
                     return;
                  }
                  jfc.setCurrentDirectory(f);
                  jfc.rescanCurrentDirectory();
               }
            });
         for (int i = 0; i < 100; i++) {
            f.mkdirs();
            f.delete();
         }
      }
   }
   
   
   private static void start() {
      jfc = new JFileChooser();
      jfc.showOpenDialog(null);
   }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
I suppose you could use a FileSystemView wrapper that handles all the problems, but if I remember correctly, some of the file chooser UIs do special-case stuff if the matching FileSystemView subclass is used (which shouldn't be the case, but that is another issue).