java new File() hangs on stale NFS mount point

Viewed 1299

In my java code i'm reading a NFS mounted directory (code runs on NFS client machine). Everything's fine as long as NFS server machine is up and running but when the NFS server is down (for any reason), the code hangs anywhere that creating new File to nfs mounted directory. If i simply umount the nfs directory, my code runs with no problem, but i don't want to manually check for such a problems every day and wanted to handle this scenario only in my code

this is /etc/exports of NFS Server:

/var/nfs/general *(rw,insecure,all_squash,no_subtree_check)

The actual java code is simply:

log.info("before new");
File file = new File("/var/nfs/general");
log.info("after new");

It only prints "before new" in log file and never reaches the "after new"

I put the new File in Executor service with timeout like what this suggested but still hangs even with 2 seconds timeout:

How do I call some blocking method with a timeout in Java?

  • OS: ubuntu server 16.04 on both servers (NFS client and server)

    Java version: 1.8_172

1 Answers

You can simply wrap it under a Callable and use get() with a timeout. Below is a sample code which can timeout after 20 seconds if result(File here) is not available!

FutureTask<File> futureFile = new  FutureTask<File>(new Callable<File>(){
    public File call() throws Exception {
        return new File(filePath);
    }
});

futureFile.get(20, TimeUnit.SECONDS);

I've made the timeout to 3 ns for testing purpose. File would surely be timed-out in this case.

public static File readTimeOut(final String filePath, int timeOutInMillis) throws InterruptedException, ExecutionException, TimeoutException {
        ExecutorService executor = Executors.newFixedThreadPool(1);
        FutureTask<File> futureFile = new FutureTask<File>(new Callable<File>() {

            public File call() throws Exception {
                System.out.println("I am called");
                return new File("/usr/mohamed");
            }
    });
    executor.execute(futureFile);
    return futureFile.get(3, TimeUnit.NANOSECONDS);
}

(Kept everything simple. Resources aren't closed properly!) But this can surely be handled with FutureTask.

Related