4

I have a Java program that executes Runtime.getRuntime().exec("ls -l"); many times, once for each directory in the system.

My test system has more than 1,000 directories and Runtime.getRuntime().exec("ls -l"); seems to error out after 480 directories or so. The error message I'm getting is is "Error running exec(). Command: [ls, -l] Working Directory: null Environment: null". I'm guessing it's running out of some required system resources or is it? Is there any way to process all directories without erroring out?

Relative comment from an answer:

I should clarify that I was using Android SDK's adb.exe. I wanted to execute something like Runtime.getRuntime().exec("adb shell ls -l") multiple times on different directories.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
ytw
  • 1,335
  • 2
  • 20
  • 42
  • 1
    Does it fail on some specific directory or it's a random directory every time? – Andrew Logvinov Mar 05 '12 at 18:41
  • You might be able to try performing the steps in the answer outlined at http://stackoverflow.com/questions/5963741/java-io-ioexception-error-running-exec-commands-cd-sdcard-yasmin-workin to see if that will help. – Zack Macomber Mar 05 '12 at 18:46
  • Random directories. It seems to fail after listing 480 directories or so. After it failed, if I call Runtime.getRuntime().exec("ls -l"); again without restarting the program, it fails at the first directory that it sees. – ytw Mar 05 '12 at 18:49
  • Are you waiting for each `ls -l` process to complete, or are you executing the commands all possibly in parallel? There's a `Process.waitFor()` method that will make sure each process has exited. If you don't wait for the process to exit, it might still be running, which may consume some system resources. http://docs.oracle.com/javase/6/docs/api/java/lang/Process.html#waitFor%28%29 – jbindel Mar 05 '12 at 19:05
  • Hi, Fly I'm already using waitFor(). Thanks for taking the time to help. – ytw Mar 05 '12 at 19:39

2 Answers2

7

You should explicitly close the input/output streams when using Runtime.getRuntime().exec.

Process p = null;
try {
    p = Runtime.getRuntime().exec("ls -l");
    //process output here
    p.waitFor();
} finally {
    if (p != null) {
        p.getOutputStream().close();
        p.getInputStream().close();
        p.getErrorStream().close(); 
    }
}
Narendra Yadala
  • 9,554
  • 1
  • 28
  • 43
  • 1
    You may want to add `p.destroy()` to the finally list. – ɲeuroburɳ Mar 05 '12 at 18:58
  • 1
    Exactly. Without closing the streams, OP will probably run out of file descriptors before he can run out of memory. – Michał Kosmulski Mar 05 '12 at 19:05
  • 2
    Rather than `destroy()` the processes, I would suggest using `waitFor()` to let them complete normally. Using `destroy()` "forcibly terminates" the process, which is a drastic thing to do if unless you know the process is not working. – jbindel Mar 05 '12 at 19:08
  • As Narendra Yadala said, you mus explicitly close the input- and output streams of the process, preferably in a finally block, BUT from my experience, that alone won't help in this situation. It seems that per-process stdout/stderr -streams in Linux/Unix have some sort of internal buffer, and when that buffer fills, the process you are running stops waiting for someone (ie. your Java-application) to read out the data from those streams before it continues. If you don't do this, the processes will just sit there, and at some point you'll run out of some system resource (like open files or maxim – esaj Mar 05 '12 at 18:54
  • Closing the input/output streams indeed fixed the problem. Thanks! – ytw Mar 05 '12 at 19:36
  • As long as `p.waitFor()` is in the non-exceptional path, putting `p.destroy()` in the finally list is probably better than closing each stream unless you also want to handle exceptions from each `close()` method. – jbindel Mar 05 '12 at 19:37
2

It would be better to use java.io.File and the appropriate methods on those classes for walking and manipulating the file system.

You don't say why you are doing this degenerate behavior this way but here is an example of listing all the files in a tree.