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;
36 public class SimpleProcess {
37 private static final Log LOG = LogFactory.getLog(SimpleProcess.class);
39 private File directory;
43 private String stdout;
45 private String stderr;
48 * Creates a new SimpleProcess object.
51 public SimpleProcess(File aDirectory, String[] aCmd) {
52 directory = aDirectory;
60 public String getStdout() {
68 public String getStderr() {
73 * Runs the process and blocks until it is done.
75 * @return Exit status of the process.
78 * In case of problems.
80 public int run() throws IOException {
84 private int runImpl() throws IOException {
88 for (String part : cmd) {
89 fullcmd += (" " + part);
92 LOG.debug("Executing '" + fullcmd + "' in directory '" + directory +
95 java.lang.Process proc = Runtime.getRuntime().exec(cmd, null,
98 // Read standard output and error in separate threads to avoid
100 StringWriter myStdout = new StringWriter();
101 StringWriter myStderr = new StringWriter();
102 Thread stdoutReader = readAndLogStream("STDOUT> ", proc
103 .getInputStream(), myStdout);
104 Thread stderrReader = readAndLogStream("STDERR> ", proc
105 .getErrorStream(), myStderr);
109 } catch (InterruptedException e) {
110 IOException exception = new IOException(
111 "Process was terminated: " + this);
112 exception.initCause(e);
116 waitForReader(stdoutReader);
117 waitForReader(stderrReader);
119 stdout = myStdout.toString();
120 stderr = myStderr.toString();
122 if (proc.exitValue() != 0) {
123 LOG.warn("Exit value was non-zero: " + this);
125 LOG.debug("Process finished");
128 return proc.exitValue();
129 } catch (IOException e) {
130 IOException exception = new IOException(
131 "Error executing process: " + this);
132 exception.initCause(e);
137 private void waitForReader(Thread aReaderThread) {
139 aReaderThread.join();
140 } catch (InterruptedException e) {
143 ": error waiting for output stream reader of process to finish");
147 private Thread readAndLogStream(final String aPrefix,
148 final InputStream aStream, final Writer aOutput) {
149 Thread inputReader = new Thread() {
152 BufferedReader br = null;
155 br = new BufferedReader(new InputStreamReader(aStream));
159 while ((str = br.readLine()) != null) {
160 LOG.debug(aPrefix + str);
163 } catch (IOException e) {
164 LOG.warn(SimpleProcess.this +
165 ": error reading input stream", e);
170 } catch (IOException e) {
171 LOG.warn("Error closing stream " + aPrefix);
184 public String toString() {
187 for (String part : cmd) {
188 fullcmd += (part + " ");
191 return "process(dir = '" + directory + "', cmd = '" + fullcmd + "')";