Wiki source code of Calling Commandline Applications
Last modified by Pascal Robert on 2012/08/11 18:16
Show last authors
| author | version | line-number | content |
|---|---|---|---|
| 1 | = The Project Wonder way = | ||
| 2 | |||
| 3 | Project Wonder, in the ERExtensions framework, have a utility class to help you run command-line applications, [[ERXRuntimeUtilities>>url:http://jenkins.wocommunity.org/job/Wonder/javadoc/er/extensions/foundation/ERXRuntimeUtilities.html||shape="rect"]]. This utility class is used inside Wonder, for example ERAttachment use it to call ImageMagick when you want to resize images. | ||
| 4 | |||
| 5 | Check the Javadoc for the [[execute>>url:http://jenkins.wocommunity.org/job/Wonder/javadoc/er/extensions/foundation/ERXRuntimeUtilities.html#execute||shape="rect"]] method to see examples. | ||
| 6 | |||
| 7 | = The Java way = | ||
| 8 | |||
| 9 | Here, the "cat" and "outputCat" are debugging output categories: | ||
| 10 | |||
| 11 | {{code}} | ||
| 12 | |||
| 13 | Process process=null; | ||
| 14 | try { | ||
| 15 | process = Runtime.getRuntime().exec(commandLine); | ||
| 16 | OutputStream output = process.getOutputStream(); | ||
| 17 | output.write(inputString.getBytes()); | ||
| 18 | output.close(); | ||
| 19 | process.waitFor(); | ||
| 20 | DataInputStream dis=new DataInputStream(process.getInputStream()); | ||
| 21 | String output; | ||
| 22 | do { | ||
| 23 | output = dis.readLine(); | ||
| 24 | if (output != null) | ||
| 25 | outputCat.debug(output); | ||
| 26 | } while (output != null); | ||
| 27 | dis.close(); | ||
| 28 | } catch (IOException e) { | ||
| 29 | cat.error("IOException: " + e.toString()); | ||
| 30 | } catch (InterruptedException e) { | ||
| 31 | cat.error("Interrupted process: " + e.toString()); | ||
| 32 | } finally { | ||
| 33 | if (process != null) | ||
| 34 | process.destroy(); | ||
| 35 | outputCat.debug("Process finished."); | ||
| 36 | } | ||
| 37 | |||
| 38 | {{/code}} | ||
| 39 | |||
| 40 | Note: A number of people have reported problems with process.waitFor() on Windows. The WebObjects Development List at Omnigroup has a number of people's workaround code for this problem. | ||
| 41 | |||
| 42 | **Note 2:** The procedure given here, of course, is to call anything executable from the command line from your Java program, not just Perl scripts. | ||
| 43 | |||
| 44 | === Mike Schrag === | ||
| 45 | |||
| 46 | process.waitFor() is not just a problem on Windows. This code //will// cause problems. Process maintains buffers for stdout and stderr. If you do not consume those streams, you will run into deadlocks. The proper way to use Runtime.exec is to setup a thread for stderr and a thread for stdout and consume them yourself into your own buffer that does not have the same restrictions that the stock VM has. | ||
| 47 | |||
| 48 | There's a good example of this technique on [[JavaWorld>>url:http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html||shape="rect"]]. |