Wiki source code of Calling Commandline Applications
Version 6.1 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>>http://jenkins.wocommunity.org/job/Wonder/javadoc/er/extensions/foundation/ERXRuntimeUtilities.html]]. 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>>http://jenkins.wocommunity.org/job/Wonder/javadoc/er/extensions/foundation/ERXRuntimeUtilities.html#execute]] 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>>http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html]]. |