Java Watch Service : Not Working for Remote Files mounted in the local Server
Asked Answered
I

3

9

I have Java program monitoring a remote folder mounted in my local server. But it is not detecting any changes / modification whenever something changed in the remote folder.

It is working fine if the changes / modification is made in the mounted folder.

Searching through net, as mention in the Java docs

If a watched file is not located on a local storage device then it is implementation specific if changes to the file can be detected. In particular, it is not required that changes to files carried out on remote systems be detected.

Anyone could help provide me sample on how to do this? below is my current code

WatchService watcher = FileSystems.getDefault().newWatchService();
    Path dir = Paths.get(directory);
    dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);

    while (true) {

        WatchKey key;
        try {
            key = watcher.take();
        } catch (Exception ex) {
            return;
        }

        for (WatchEvent<?> event : key.pollEvents()) {
            WatchEvent.Kind<?> kind = event.kind();

            @SuppressWarnings("unchecked")
            WatchEvent<Path> ev = (WatchEvent<Path>) event;
            Path fileName = ev.context();

            if (kind == ENTRY_MODIFY) {
                    System.out.println("file has changed");
                   // other process    
            }
           if (kind == ENTRY_CREATE) {
                  System.out.println("file has created");
                  // other process
           }
        }

        boolean valid = key.reset();
        if (!valid) {
            break;
        }
   }
Ibo answered 22/2, 2018 at 3:18 Comment(0)
S
5

I have same issue and used org.apache.commons.io.monitor.FileAlterationMonitor. The pom.xml changes as suggested in the post before is as below

<dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.6</version>
</dependency>

Code Snippet for usage which is working for me is as below:

    String monitoringDirectory= "<YOUR CODE HERE>"; 
    FileAlterationObserver observer = new FileAlterationObserver(monitorDirectory);

    logger.info("Start ACTIVITY, Monitoring "+monitorDirectory);
    observer.addListener(new FileAlterationListenerAdaptor(){
         @Override
         public void onDirectoryCreate(File file) {
            logger.info("New Folder Created:"+file.getName());
         }

         @Override
         public void onDirectoryDelete(File file) {
             logger.info("Folder Deleted:"+file.getName());
         } 

         @Override
         public void onFileCreate(File file) {
             logger.info("File Created:"+file.getName()+": YOUR ACTION");

         }

         @Override
         public void onFileDelete(File file) {
             logger.info("File Deleted:"+file.getName()+": NO ACTION");
         }  
      });
    /* Set to monitor changes for 500 ms */     
    FileAlterationMonitor monitor = new FileAlterationMonitor(500, observer);
    try {
        monitor.start();
    } catch (Exception e) {
        logger.error("UNABLE TO MONITOR SERVER" + e.getMessage());
        e.printStackTrace();

    }
Sweptback answered 9/1, 2019 at 1:39 Comment(2)
What did you put in this variable? String monitoringDirectory= "<YOUR CODE HERE>"; Is it a server IP with location of the folder? Also what if the folder needs credentials in order to be accessed?Kappa
If you look at the question: 'Java program monitoring a remote folder mounted in my local server', here, the mounting of the folder and hence the required permissions are outside the scope of the application. It assumes the folder is accessible as a shared folder. 'YOUR CODE HERE' is the location of the folder which can be read by the application.Sweptback
A
0

I guess, Oracle's watch service doesn't detect remote events - that service is for local directories.

You have to use - org.apache.commons.io.monitor.FileAlterationMonitor class of API -

<dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.6</version>
</dependency>

You should google for code samples using that class.

Anticathexis answered 30/3, 2018 at 3:45 Comment(7)
It is not Oracle's fault. The problem is that remote file system protocols (e.g. NFS, SMB) don't allow you to install a watcher on the remote file server, and don't have a way to deliver (all) file events to interested clients. Therefore watching doesn't work in the client-side OS. The Java code relies on the OS.Reinhold
Put it another way, you would have the same problem if your file watcher was implemented in C.Reinhold
This library does not connect to a remote server folder based on: #35218274Kappa
The apache monitor is per interval of time so it is not a real event listenerKappa
Other blogs says that even apache commons io does not work with remote folders. What would be the solution then other than creating a thread that checks the folder each X interval of time?Kappa
@user666: You are correct that its time interval based but you can set interval to be very low to have a feel of real time ..thats how all programs work i.e. making duration small enough to be not human detectable & nothing is truly real - time . Secondly, this solution is applicable for remote directory mounted on local server. The other word for mounting is mapped drive on Windows. If remote directory is accessed via SSH , FTP , SFTP , HTTP etc etc then this solution is not applicable.Anticathexis
@user666: This is an answer to an existing question and if your question or scenario is different than this question then you first need to clarify that.Anticathexis
T
0

I also have the same issue with Java watchService in the docker container environment. Removing the volume map to the folder makes the watch service work.

Tournament answered 23/8 at 10:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.