How to read command line ouput from Java (via Runtime.getRuntime().exec(…))

I’m trying to present some information in a Swing application about the existance of symlinks. The GUI has a JTextArea resultTextArea and a JTextField statusField. This is the code inside the Dialog class:

public void checkForSymLinks(File... dirs) {
    for (File dir : dirs) {
        try {
            Process p = Runtime.getRuntime().exec("find -type l", null, dir);
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(p.getInputStream()));
            String line = null;
            while ((line = in.readLine()) != null) {
                resultTextArea.append(line);
            }
        } catch (IOException ex) {
            Logger.getLogger(SymbolicLinkSearchResultDialog.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    statusField.setText("SymLinks found! // FIXME");
}

I tried and replaced Process p = Runtime.getRuntime().exec("find -type l", null, dir); by:

ProcessBuilder pb = new ProcessBuilder("find -type l");
pb.directory(dir).redirectErrorStream(true);
Process p = pb.start(); 

But that did not help.

The problem is that it somehow neither writes anything to the resultTextArea nor reaches the code to set the statusField in the last line. It seems to hang somewhere, alhough the GUI stays responsive.

I get the following stacktrace upon closing the dialog:

java.io.IOException: Cannot run program "find -type l" (in directory "/home/johndoe/Desktop/test"): error=2, No such file or directory
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1024)

I already tried /usr/bin/find type -l and many other things… Any ideas what I’m done wrong?

PS: Operationg system is Linux.

Weird thing:

def symLinkCheck(dirs: Array[File]) = {                              
  dirs.foreach{ dir =>                                                        
    val p = Runtime.getRuntime().exec("find -type l", null, dir)                    
    val in = new BufferedReader(new InputStreamReader(p.getInputStream)) 
    var line: String = null
    while({line = in.readLine; line} != null){
      println(line)
    }
  }
}

I tried this code in Scala and it worked without a problem. I’m not really sure anymore if my problem is maybe related to Swing?

EDIT: The problem is definitely related to Swing.

If I call the method before theGUI.setVisible(true) it works, but after that it doesn’t.

I already tried SingUtilities.invokeLater but that didn’t help.

Answer

I found the Problem: The method was not called from the event dispatch thread, after the GUI was constrcuted.

Leave a Reply

Your email address will not be published. Required fields are marked *