2 * Copyright 2007 the original author or authors.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.wamblee.io;
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
21 import java.io.BufferedReader;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.InputStreamReader;
26 import java.io.OutputStream;
27 import java.io.PrintStream;
28 import java.io.StringWriter;
29 import java.io.Writer;
38 public class SimpleProcess {
42 private static final Log LOG = LogFactory.getLog(SimpleProcess.class);
47 private File directory;
57 private String stdout;
62 private String stderr;
65 * Creates a new SimpleProcess object.
67 * @param aDirectory DOCUMENT ME!
68 * @param aCmd DOCUMENT ME!
70 public SimpleProcess(File aDirectory, String[] aCmd) {
71 directory = aDirectory;
80 public String getStdout() {
89 public String getStderr() {
94 * Runs the process and blocks until it is done.
96 * @return Exit status of the process.
98 * @throws IOException In case of problems.
100 public int run() throws IOException {
107 * @return DOCUMENT ME!
109 * @throws IOException DOCUMENT ME!
111 private int runImpl() throws IOException {
115 for (String part : cmd) {
116 fullcmd += (" " + part);
119 LOG.debug("Executing '" + fullcmd + "' in directory '" + directory
122 java.lang.Process proc = Runtime.getRuntime()
123 .exec(cmd, null, directory);
125 // Read standard output and error in separate threads to avoid
127 StringWriter myStdout = new StringWriter();
128 StringWriter myStderr = new StringWriter();
129 Thread stdoutReader = readAndLogStream("STDOUT> ",
130 proc.getInputStream(), myStdout);
131 Thread stderrReader = readAndLogStream("STDERR> ",
132 proc.getErrorStream(), myStderr);
136 } catch (InterruptedException e) {
137 IOException exception = new IOException(
138 "Process was terminated: " + this);
139 exception.initCause(e);
143 waitForReader(stdoutReader);
144 waitForReader(stderrReader);
146 stdout = myStdout.toString();
147 stderr = myStderr.toString();
149 if (proc.exitValue() != 0) {
150 LOG.warn("Exit value was non-zero: " + this);
152 LOG.debug("Process finished");
155 return proc.exitValue();
156 } catch (IOException e) {
157 IOException exception = new IOException("Error executing process: "
159 exception.initCause(e);
167 * @param aReaderThread DOCUMENT ME!
169 private void waitForReader(Thread aReaderThread) {
171 aReaderThread.join();
172 } catch (InterruptedException e) {
174 + ": error waiting for output stream reader of process to finish");
181 * @param aPrefix DOCUMENT ME!
182 * @param aStream DOCUMENT ME!
183 * @param aOutput DOCUMENT ME!
185 * @return DOCUMENT ME!
187 private Thread readAndLogStream(final String aPrefix,
188 final InputStream aStream, final Writer aOutput) {
189 Thread inputReader = new Thread() {
192 BufferedReader br = null;
195 br = new BufferedReader(new InputStreamReader(aStream));
199 while ((str = br.readLine()) != null) {
200 LOG.debug(aPrefix + str);
203 } catch (IOException e) {
204 LOG.warn(SimpleProcess.this
205 + ": error reading input stream", e);
210 } catch (IOException e) {
211 LOG.warn("Error closing stream " + aPrefix);
226 * @return DOCUMENT ME!
229 public String toString() {
232 for (String part : cmd) {
233 fullcmd += (part + " ");
236 return "process(dir = '" + directory + "', cmd = '" + fullcmd + "')";