# Runtime.exec() => java.io.exception: too many open files



## michah (7. Sep 2004)

Nach einigen hundert Aufrufen mit Runtime.exec() bekomme ich folgende Exception:
java.IO.Exception: Too many open files
Ich weis dass der Fehler an den Stream-handels liegt, bzw. dass nicht alle geschlossen
werden, nur weis ich nicht welche Handels noch offen sind (siehe Klasse unten).
Kann mir jemand helfen.

Gruss und Merci
Micha Haeusermann


```
import java.io.*;

public class Execute {
    // Init
    static int exitcode = 0;
    static String errorout = "";
    static String runout = "";
    static boolean error = false;

    public static boolean runCommand(String command) {

        //Log.write("class Execute: call shell command: " + command);
        try {
            // create Runtimeobject rt
            Runtime rt = Runtime.getRuntime();
            // create Processobject pr
            Process pr = rt.exec(command);
            // wait until process is done
            pr.waitFor();
            // check for errors
            exitcode = pr.exitValue();
            // create process error reader
            BufferedReader perror = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
            // create process output reader
            BufferedReader poutput = new BufferedReader(new InputStreamReader(pr.getInputStream()));
            // write error to log
            if (exitcode != 0) {
                //Log.write("Error: class Execute: exit code: " + exitcode);
                while ((errorout = perror.readLine()) != null) {
                    //Log.write("Error: class Execute: " + errorout);
                }
                error = true;
            }
            else {
                //Log.write("class Execute: Done, exit code: " + exitcode);
            }
            // write output to runout (only first line)
            runout = poutput.readLine();
            if (runout == null) {
                runout = "";
            }
       // destroy not longer used instances
            pr.getErrorStream().close();
            pr.getInputStream().close();
            pr.getOutputStream().close();
       poutput.close();
       perror.close();
            pr.destroy();
        }
        // catch exceptions and write it to log
        catch (Exception e) {
            error = true;
            //Log.write("Error: class Execute: exception: " + e.toString());
        }
   // return true if an error occurred
        return error;
    }
}
```


----------



## Illuvatar (7. Sep 2004)

Was willst du mit ein paar hundert Programmen, da muss doch zumindest der Arbeitsspeicher ausgehen.


----------



## Bleiglanz (7. Sep 2004)

Wenn dein Code eine Exception auslöst, werden nicht alle Streams geschlossen!

Füg eine finallly Klausel hinzu, in der du nochmal alle schliesst,


```
foo.close(); // könnte ja selbst eine Exception werfen
foo = null;
bar.close(); // wenn bei foo geworfen, komm ich nicht hierher !!!!!
bar = null;
catch(Exception e){} // ist mir hier egal
finally
{
if(null!=foo) { foo.close(); // wirft vielleicht wieder, nochmal wrappen
if(null!=bar) { bar.close(); // evenso 
}
```

_Editiert von P3AC3MAK3R: Code-Tags repariert_


----------



## michah (7. Sep 2004)

Leider bringt das mit der finally-Klausel nichts, da bereits die Streams (siehe Zeile 44 - 46) geschlossen sind.


----------



## Bleiglanz (7. Sep 2004)

doch:

wenn irgendwo im try - block eine Exception fliegt, dann werden die close-Methoden nicht mehr aufgerufen (weil 44-46 dann gar nicht erreicht wird!)


----------



## michah (7. Sep 2004)

Ja das stimmt, nur fliegt erst eine Exception nach einigen hundert Aufrufen -> erst sobald keine Filehandels mehr
vorhanden sind. Also muss doch das Problem darin liegen, dass irgendwo noch ein Streamhandel offen bleibt und
dies immer wieder bei jedem Aufruf der Methode bis keine mehr zur verfügung stehen.

Als Beispiel wenn ich ein Kommando wie dieses "cp /.../filexy /.../" 1000 mal sequentiell ausführen muss, wird nach
ca. 300 Aufrufen die beschriebe Exception geworfen, obwohl ich bei jedem einzelne Prozess warte bis dieser be-
endet ist und versuche alle Streamhandels zu schliessen.
Würde ein Streamhandel nicht geschlossen, müsste ja auch eine Exception geworfen werden, oder sehe ich dies
falsch?


----------



## Bleiglanz (7. Sep 2004)

mir fällt gerade auf, dass du pr.getXXXStream zweimal aufrufst? warum?


----------



## Guest (7. Sep 2004)

Um zum einen den normalen Output des Programmes zu lesen (pr.getInputStream siehe Zeile 24) und die Fehlerausgaben zu lesen (pr.getErrorSream siehe Zeile 26) (wenn ich dem Programm etwas mitteilen wollte, würde ich pr.getOutputStream() verwenden).

Kenne eigentlich nur diese Variante um schlau mit einem Prozess zu komonizieren und das funktioniert normalerweise auch ohne
Probleme.


----------



## Bleiglanz (8. Sep 2004)

ich meinte die Zeilen zum schliessen 44-45, vielleicht ist ja das mehrfache abholen des Streams ein problem:

pr.getErrorStream().close();


----------



## Guest (9. Sep 2004)

Das Verhalten ändert auch nicht wenn ich die Zeilen 44 & 45 entferne (46 brauche ich, da sonst der OutputStream nicht geschlossen wird).


----------



## Guest (21. Sep 2004)

Einfachste und unsaubere Lösung:

- mit ulimit -a die max Anzahl der offenen Files ermitteln
- mit ulimit -n diesen Wert erhöhen


----------

