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 java.io.BufferedReader;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.InputStreamReader;
23 import java.io.OutputStream;
24 import java.io.PrintStream;
25 import java.io.StringWriter;
26 import java.io.Writer;
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
31 public class SimpleProcess {
33 private static final Log LOG = LogFactory.getLog(SimpleProcess.class);
35 private File _directory;
37 private String[] _cmd;
39 private String _stdout;
40 private String _stderr;
42 public SimpleProcess(File aDirectory, String[] aCmd) {
43 _directory = aDirectory;
50 public String getStdout() {
57 public String getStderr() {
62 * Runs the process and blocks until it is done.
64 * @return Exit status of the process.
66 * In case of problems.
68 public int run() throws IOException {
72 private int runImpl() throws IOException {
75 for (String part: _cmd) {
76 fullcmd += " " + part;
78 LOG.debug("Executing '" + fullcmd + "' in directory '" + _directory
80 java.lang.Process proc = Runtime.getRuntime().exec(_cmd, null, _directory);
82 // Read standard output and error in separate threads to avoid
85 StringWriter stdout = new StringWriter();
86 StringWriter stderr = new StringWriter();
87 Thread stdoutReader = readAndLogStream("STDOUT> ", proc
88 .getInputStream(), stdout);
89 Thread stderrReader = readAndLogStream("STDERR> ", proc
90 .getErrorStream(), stderr);
94 } catch (InterruptedException e) {
95 IOException exception = new IOException(
96 "Process was terminated: " + this);
97 exception.initCause(e);
100 waitForReader(stdoutReader);
101 waitForReader(stderrReader);
103 _stdout = stdout.toString();
104 _stderr = stderr.toString();
106 if (proc.exitValue() != 0) {
107 LOG.warn("Exit value was non-zero: " + this);
109 LOG.debug("Process finished");
111 return proc.exitValue();
112 } catch (IOException e) {
113 IOException exception = new IOException("Error executing process: "
115 exception.initCause(e);
120 private void waitForReader(Thread aReaderThread) {
122 aReaderThread.join();
123 } catch (InterruptedException e) {
126 + ": error waiting for output stream reader of process to finish");
130 private Thread readAndLogStream(final String aPrefix,
131 final InputStream aStream, final Writer aOutput) {
132 Thread inputReader = new Thread() {
135 BufferedReader br = null;
137 br = new BufferedReader(new InputStreamReader(aStream));
139 while ((str = br.readLine()) != null) {
140 LOG.debug(aPrefix + str);
143 } catch (IOException e) {
144 LOG.warn(SimpleProcess.this + ": error reading input stream", e);
149 } catch (IOException e) {
150 LOG.warn("Error closing stream " + aPrefix);
161 public String toString() {
163 for (String part: _cmd) {
164 fullcmd += part + " ";
166 return "process(dir = '" + _directory + "', cmd = '" + fullcmd + "')";