001: package snow.utils;
002:
003: import java.io.*;
004: import java.util.*;
005:
006: public final class ProcessUtils {
007: private ProcessUtils() {
008: }
009:
010: /** DON'T USE the returned process streams, they are already gobbled.
011: * Only sense: look at exit value (with waitFor(), the exitValue is buggy on linux...)
012: */
013: public static Process executeProcessAndGobble(String descr,
014: File execDir, String... processArgs) throws Exception {
015: return executeProcessAndGobble(Arrays.asList(processArgs),
016: execDir, descr, null, null);
017: }
018:
019: /** DON'T USE the returned process streams, they are already gobbled.
020: * Only sense: look at exit value (WARNING: use waitFor(), the exitValue is buggy on linux...)
021: */
022: public static Process executeProcessAndGobbleToConsole(
023: String descr, File execDir, String... processArgs)
024: throws Exception {
025: return executeProcessAndGobble(Arrays.asList(processArgs),
026: execDir, descr, System.out, System.err);
027: }
028:
029: /** Executes the command and gobbles the whole output, don't waits.
030: * @return the process, can be used to waitFor, but not to gobble because
031: * it is already gobbled to nowhere !
032: */
033: public static Process executeProcessAndGobble(
034: final List<String> processArgs, File execDir, String descr,
035: OutputStream out, OutputStream errOut) throws Exception {
036: Process proc = null;
037: if (execDir != null) {
038: proc = Runtime.getRuntime()
039: .exec(
040: processArgs.toArray(new String[processArgs
041: .size()]), null, execDir);
042: } else {
043: proc = Runtime.getRuntime()
044: .exec(
045: processArgs.toArray(new String[processArgs
046: .size()]));
047: }
048:
049: StreamGobbler sg1 = new StreamGobbler(proc.getInputStream(),
050: out);
051: sg1.setName("Gobbler " + descr + " (in)");
052: sg1.start();
053: StreamGobbler sg2 = new StreamGobbler(proc.getErrorStream(),
054: errOut);
055: sg2.start();
056: sg2.setName("Gobbler " + descr + " (err)");
057:
058: return proc;
059: }
060:
061: /** Executes the process and drain the output...
062: * DON't use the process outputs, they are already gobbled
063: */
064: public static Process executeProcessAndGobble(
065: final List<String> processArgs, String descr)
066: throws Exception {
067: return executeProcessAndGobble(processArgs, null, descr, null,
068: null);
069: }
070:
071: public static String readWholeProcessStack(
072: final String... processArgs) throws Exception {
073: return readWholeProcessStack(Arrays.asList(processArgs));
074: }
075:
076: /** @return a text with the full output of the process.
077: Err and Out mixed.
078: Use it only for small debugs or options reading from a program
079: Has a 10 sec timeout.
080: */
081: public static String readWholeProcessStack(
082: final List<String> processArgs) throws Exception {
083: return readWholeProcessStack(processArgs, 10000L);
084: }
085:
086: /** @return a text with the full output of the process.
087: Err and Out mixed.
088: Use it only for small debugs or options reading from a programm.
089: */
090: public static String readWholeProcessStack(
091: final List<String> processArgs, final long timeout)
092: throws Exception {
093: Process proc = Runtime.getRuntime().exec(
094: processArgs.toArray(new String[processArgs.size()]));
095: ByteArrayOutputStream baos = new ByteArrayOutputStream();
096: StreamGobbler sg1 = new StreamGobbler(proc.getInputStream(),
097: baos);
098: sg1.start();
099: StreamGobbler sg2 = new StreamGobbler(proc.getErrorStream(),
100: baos);
101: sg2.start();
102: if (timeout > 0) {
103: sg1.join(timeout);
104: sg2.join(timeout);
105: } else {
106: sg1.join();
107: sg2.join();
108: }
109:
110: return new String(baos.toByteArray());
111: }
112:
113: /** @return a text with the full output of the process. (With a timeout of 10 secs)
114: Err and Out mixed.
115: Use it only for small debugs or options reading from a program 10 sec timeout
116: */
117: public static String readWholeProcessStack(
118: final List<String> processArgs, final File execDir,
119: long timeout) throws Exception {
120: return readWholeProcessStack(processArgs, execDir, null,
121: timeout, false);
122: }
123:
124: /** @return a text with the full output of the process.
125: Err and Out mixed.
126: Use it only for small debugs or options reading from a program.
127: */
128: public static String readWholeProcessStack(
129: final List<String> processArgs, final File execDir,
130: final List<String> toType, long timeout,
131: boolean errorIfNotStatusExit0) throws Exception {
132: Process proc = Runtime.getRuntime().exec(
133: processArgs.toArray(new String[processArgs.size()]),
134: null, // inherits current process env.
135: execDir);
136:
137: ByteArrayOutputStream baos = new ByteArrayOutputStream();
138: StreamGobbler sg1 = new StreamGobbler(proc.getInputStream(),
139: baos);
140: sg1.start();
141: StreamGobbler sg2 = new StreamGobbler(proc.getErrorStream(),
142: baos);
143: sg2.start();
144:
145: if (toType != null) {
146: for (final String tt : toType) {
147: proc.getOutputStream().write(tt.getBytes());
148: proc.getOutputStream().flush();
149: }
150: }
151:
152: // Wait until completion.
153: if (timeout > 0) {
154: sg1.join(timeout);
155: sg2.join(timeout);
156: } else {
157: sg1.join();
158: sg2.join();
159: }
160:
161: // Well: process make an exception if not exited (if timeout passed above !). this is good...
162: int ev = proc.waitFor(); // BUG: on linux, proc.exitValue() fails for shell scripts.
163: // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4487518
164:
165: String stack = new String(baos.toByteArray());
166:
167: if (errorIfNotStatusExit0 && ev != 0)
168: throw new RuntimeException("Exit value was " + ev
169: + "\nstack: " + stack);
170:
171: return stack;
172: }
173:
174: /** Use this to avoid hanging processes. They must be drained !!! (see java puzzlers )
175: * @param timeout -1 => waits until completion (maybe ad aeternum)
176: * DANGEROUS IF THE PROCESS HAS ALREADY BEEN DRAINED.
177: */
178: private static String readWholeProcessStack(final Process proc,
179: long timeout) throws Exception {
180: final ByteArrayOutputStream baos = new ByteArrayOutputStream();
181: StreamGobbler sg1 = new StreamGobbler(proc.getInputStream(),
182: baos, "outt");
183: sg1.start();
184: StreamGobbler sg2 = new StreamGobbler(proc.getErrorStream(),
185: baos, "errr");
186: sg2.start();
187: if (timeout > 0) {
188: sg1.join(timeout);
189: sg2.join(timeout);
190: } else {
191: // waits until completion.
192: sg1.join();
193: sg2.join();
194: }
195: return new String(baos.toByteArray());
196: }
197:
198: /** Ignores the whole outputs. Must be called when processes are created and output is not read,
199: * otherwise, probmels araises, see Java puzzlers
200: */
201: public static void drainProcess(Process proc, boolean waitCompletion) {
202: StreamGobbler sg1 = new StreamGobbler(proc.getInputStream(),
203: null);
204: sg1.start();
205: StreamGobbler sg2 = new StreamGobbler(proc.getErrorStream(),
206: null);
207: sg2.start();
208:
209: if (waitCompletion) {
210: try {
211: sg1.join();
212: sg2.join();
213: } catch (InterruptedException ie) {
214: ie.printStackTrace();
215: }
216: }
217: }
218: }
|