Search code examples
javaspringdockervfsapache-commons-vfs

Apache commons VFS cannot resolve files with String URI


I'm trying to access and read files through a Spring boot web application by using Apache Commons VFS v2.6.0. The web application is running in a hosted docker container and a separate AWS storage was mounted in the same docker by targeting /mnt. When I try to access a file/folder inside the /mnt (ex: /mnt/abc/def/ghi.csv) using the below code,

fileSystemManager = VFS.getManager();
fileSystemManager.resolveFile("/mnt/abc/def/ghi.csv")

it throws the following exception.

Could not find file with URI "/mnt/abc/def/ghi.csv because it is a relative path, and no base URI was provided.

I have made sure that Jsch jar files are also available in the classpath(Jsch v0.1.54). the strange thing in here is I can read/write files using Java File IO without any problem in the same location.

Since it is saying the Base URI was not provided I've tried by giving the base file in Java File IO format and then it was able to resolve the file object.

fileSystemManager.resolveFile(new File("/mnt/abc/def"),"ghi.csv")

Once the base file is passed with the first call then it is working perfectly after that.

I'm using VFS to resolve files in both file: and sftp: schemes

Any idea to solve the issue in a better way? If we can set a base file when fileSystemManager is initializing for the first time and then resolving the files only by giving string path that would be ideal.


Solution

  • After so many attempts I was able to found the issue myself and thought to mention it here so it might be helpful to someone.

    Short Answer : remove any occurence of fileSystemManager.close()

    Detailed Answer : This is how I dealt with FileSystemManager in my code. I'm always using VFS.getManager() to get a FileSystemManager instance and nowhere else custom FileSystemManagers are created by my own.

      if (fileSystemManager == null) {
            fileSystemManager = VFS.getManager();
      }
    

    In one place I have closed the FileSystemManager singleton which I obtained from the above method through fileSystemManager.close() in order to release the resource. But in another method which is totally independent from the first method which it has used and closed the fileSystemManager instance, is again trying to use the same fileSystemManager.

    So once the fileSystemManager is closed, most of the components like providers, fileCache, etc... which are inside the fileSystemManager are set to null but the fileSystemManager singleton is still not null. So program will skip the If condition and trying to resolve the filePath with a fileSystemManager that has no Components in it.

    Even this is clearly said in the documentation itself and noticed after I discovered the issue.

    Closes the given file system.

    If you use VFS as singleton it is VERY dangerous to call this method.

    Once fileSystemManager.close() is removed, problem solved.