There appears to be a race condition possibly somewhere in the BasicVFSDirectoryModel class that sometimes causes the contents of a directory to appear empty. This condition can happen when a VFSJFileChooser is created with an SftpFileObject. When showOpenDialog() is invoked the dialog appears with the correct directory shown in the "Look In" combo box, but the contents of the directory appears empty. I've noticed that this condition arises when the "Basic L&F File Loading Thread" is interrupted by validateFileCache() or invalidateFileCache() in the BasicVFSDirectoryModel class causing the java.io.PipedInputStream class to throw an InterruptedIOException resulting in VFSUtils.getFiles() failing.
I've been accessing files over SFTP. Our SFTP server has the following directory structure:
/usr/local/dirA/dirB
containing 1 directory (dirC) and 1 file.
/usr/local/dirA/dirB/dirC
containing 1 directory (dirD) and 4 files.
/usr/local/dirA/dirB/dirC/dirD
containing 1 file.
To reproduce the issue I do the following:
1. Create a VFSJFileChooser.
2. Present the open dialog.
3. Connect to the SFTP server specifying /usr/local/dirA/dirB as the default remote path.
4. Navigate to dirD then select the single file in that directory and click open.
5. Create another VFSJFileChooser this time with the current directory set to dirD.
6. Present the open dialog.
7. Navigate up one level to dirC.
8. Click cancel.
9. Repeat steps 5 to 7 immediately after step 8 until the bug appears.
I'm running version 0.0.3 of VFSJFileChooser with version 0.1.39 of the jsch library (I had to upgrade to 0.1.39 in order to successfully make an SFTP connection). I'm running with java 1.5, but i've tried java 6 and still have the same problem.
See below for a simple class that pops up a JFrame with a button you can click to present a VFSJFileChooser dialog. When a file is selected, the current directory is saved and used as the default directory next time the button is pressed.
public class Test
{
public static void main(String[] args) throws FileSystemException
{
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(new JButton(new AbstractAction("choose file")
{
FileObject chosenDir = null;
public void actionPerformed(ActionEvent e)
{
final VFSJFileChooser chooser = chosenDir == null ? new VFSJFileChooser() : new VFSJFileChooser(chosenDir);
chooser.setAccessory(new DefaultAccessoriesPanel(chooser));
try {
if (chooser.showOpenDialog(frame) == VFSJFileChooser.RETURN_TYPE.APPROVE) {
chosenDir = chooser.getSelectedFile();
if (chosenDir.getType() != FileType.FOLDER) {
chosenDir = chosenDir.getParent();
}
}
}
catch (FileSystemException ex) {
ex.printStackTrace();
chosenDir = null;
}
}
}));
frame.pack();
frame.setVisible(true);
}
}