Dienstag, 8. Januar 2013

Programmaufrufe aus Java

Manchmal ist das ja die letzte Lösung, einfach ein Kommandozeilen-Programm  aufzurufen. Die Google-Suche spuckt da im groben und ganzen immer den gleichen Tipp aus:

       ...
       Runtime runtime = Runtime.getRuntime();
       Process process = runtime.exec(args);
       InputStream is = process.getInputStream();
       ...

An der Zeile ist zunächst nichts falsch und das aufgerufene Programm wird ordnungsgemäß ausgeführt. Allerdings kann es, vorzugsweise unter Windows, beim lauschen am Input- oder Error-Stream zu einem Deadlock kommen. Hierfür ist ein Windows-Bug verantwortlich, der von der Java-VM nicht umschifft wird. Auch der Aufruf von waitFor ist dazu geeignet niemals zurück zu kommen, jedoch notwendig, wenn mit der Verarbeitung auf das Ende des Aufrufs gewartet werden soll.

Als Lösung bietet sich ein Timeout-Thread an, der den Prozess nach einer vordefinierten Zeit abbricht. Dieses und einiges mehr bietet die Apache Commons Exec-Bibliothek. Die Tutorial-Seite weist auf alles wichtige, wie auch auf Fallstricke, wie der Klassiker mit den Leerzeichen in Pfadangaben hin.

Dazu passend gibt es auf Java Code Geeks eine Javaklasse, die das ganze hübsch in ein objektorientiertes Schema zusammenfasst. Die Klasse und das dazugehörige Interface habe ich mal der Bequemlichkeit halber hier abgelegt: ProcessExecutor.java, ProcessExecutorHandler.java.

Eine lesenswerte Analyse, was da beim Stream lesen nun genau hängt, findet man übrigens auf dem Weblog von Kohsuke Kawaguchi.

Keine Kommentare:

Kommentar veröffentlichen