2 * Copyright 2005-2010 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;
30 import java.util.Arrays;
37 public class SimpleProcess {
38 private static final Log LOG = LogFactory.getLog(SimpleProcess.class);
40 private File directory;
44 private String stdout;
46 private String stderr;
49 * Creates a new SimpleProcess object.
52 public SimpleProcess(File aDirectory, String[] aCmd) {
53 directory = aDirectory;
54 cmd = Arrays.copyOf(aCmd, aCmd.length);
61 public String getStdout() {
69 public String getStderr() {
74 * Runs the process and blocks until it is done.
76 * @return Exit status of the process.
79 * In case of problems.
81 public int run() throws IOException {
85 private int runImpl() throws IOException {
87 StringBuffer fullcmd = new StringBuffer();
89 for (String part : cmd) {
90 fullcmd.append(" " + part);
93 LOG.debug("Executing '" + fullcmd + "' in directory '" + directory +
96 java.lang.Process proc = Runtime.getRuntime().exec(cmd, null,
99 // Read standard output and error in separate threads to avoid
101 StringWriter myStdout = new StringWriter();
102 StringWriter myStderr = new StringWriter();
103 Thread stdoutReader = readAndLogStream("STDOUT> ", proc
104 .getInputStream(), myStdout);
105 Thread stderrReader = readAndLogStream("STDERR> ", proc
106 .getErrorStream(), myStderr);
110 } catch (InterruptedException e) {
111 IOException exception = new IOException(
112 "Process was terminated: " + this);
113 exception.initCause(e);
117 waitForReader(stdoutReader);
118 waitForReader(stderrReader);
120 stdout = myStdout.toString();
121 stderr = myStderr.toString();
123 if (proc.exitValue() != 0) {
124 LOG.warn("Exit value was non-zero: " + this);
126 LOG.debug("Process finished");
129 return proc.exitValue();
130 } catch (IOException e) {
131 IOException exception = new IOException(
132 "Error executing process: " + this);
133 exception.initCause(e);
138 private void waitForReader(Thread aReaderThread) {
140 aReaderThread.join();
141 } catch (InterruptedException e) {
144 ": error waiting for output stream reader of process to finish");
148 private Thread readAndLogStream(final String aPrefix,
149 final InputStream aStream, final Writer aOutput) {
150 Thread inputReader = new Thread() {
153 BufferedReader br = null;
156 br = new BufferedReader(new InputStreamReader(aStream));
160 while ((str = br.readLine()) != null) {
161 LOG.debug(aPrefix + str);
164 } catch (IOException e) {
165 LOG.warn(SimpleProcess.this +
166 ": error reading input stream", e);
171 } catch (IOException e) {
172 LOG.warn("Error closing stream " + aPrefix);
185 public String toString() {
186 StringBuffer fullcmd = new StringBuffer();
188 for (String part : cmd) {
189 fullcmd.append(part + " ");
192 return "process(dir = '" + directory + "', cmd = '" + fullcmd + "')";