-1

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.

soc
  • 27,983
  • 20
  • 111
  • 215

3 Answers3

1

You don't say which OS you're using. Assuming your find command syntax is correct (it's not correct on Mac OSX), I think you should be:

  1. consuming both stdout and stderr. You need to do this concurrently to avoid blocking behaviour. See this SO answer for more details
  2. collecting the exit code from the spawned process via Process.waitFor()
Community
  • 1
  • 1
Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
0

Instead of running a Unix command to find symlinks, you could do it in Java, by comparing the results of File.getCanonicalPath() and File.getAbsolutePath().

More details in this question.

Community
  • 1
  • 1
dogbane
  • 266,786
  • 75
  • 396
  • 414
0

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

soc
  • 27,983
  • 20
  • 111
  • 215