21 package org.matsim.core.utils.misc;
23 import java.io.BufferedReader;
24 import java.io.BufferedWriter;
26 import java.io.FileWriter;
27 import java.io.IOException;
28 import java.io.InputStreamReader;
29 import java.io.OutputStreamWriter;
30 import java.io.PrintStream;
31 import java.util.Arrays;
33 import org.apache.logging.log4j.LogManager;
34 import org.apache.logging.log4j.Logger;
44 final static Logger log = LogManager.getLogger(
ExeRunner.class);
56 public static int run(
final String cmd,
final String stdoutFileName,
final int timeout) {
57 return run(cmd, stdoutFileName, timeout, null);
60 public static int run(
final String[] cmdArgs,
final String stdoutFileName,
final int timeout) {
61 return run(cmdArgs, stdoutFileName, timeout, null);
75 public static int run(
final String cmd,
final String stdoutFileName,
final int timeout,
final String workingDirectory) {
80 public static int run(
final String[] cmdArgs,
final String stdoutFileName,
final int timeout,
final String workingDirectory) {
86 synchronized (myExecutor) {
88 long timeoutMillis = 1000L * timeout;
89 long startTime = System.currentTimeMillis();
91 while (System.currentTimeMillis() - startTime < timeoutMillis) {
93 timeoutMillis -= System.currentTimeMillis() - startTime;
94 myExecutor.wait(timeoutMillis);
96 if (myExecutor.getState().equals(Thread.State.TERMINATED)) {
100 if (!myExecutor.getState().equals(Thread.State.TERMINATED)) {
102 myExecutor.interrupt();
105 }
catch (InterruptedException e) {
106 log.info(
"ExeRunner.run() got interrupted while waiting for timeout", e);
110 return myExecutor.
erg;
115 final String[] cmdArgs;
116 final String stdoutFileName;
117 final String stderrFileName;
118 final String workingDirectory;
119 private Process
p = null;
124 public ExternalExecutor (
final String cmd,
final String stdoutFileName,
final String workingDirectory) {
127 this.stdoutFileName = stdoutFileName;
128 this.workingDirectory = workingDirectory;
129 if (stdoutFileName != null) {
130 if (stdoutFileName.endsWith(
".log")) {
131 this.stderrFileName = stdoutFileName.substring(0, stdoutFileName.length() - 4) +
".err";
133 this.stderrFileName = stdoutFileName +
".err";
136 this.stderrFileName = null;
140 public ExternalExecutor (
final String[] cmdArgs,
final String stdoutFileName,
final String workingDirectory) {
141 this.cmdArgs = cmdArgs;
143 this.stdoutFileName = stdoutFileName;
144 this.workingDirectory = workingDirectory;
145 if (stdoutFileName != null) {
146 if (stdoutFileName.endsWith(
".log")) {
147 this.stderrFileName = stdoutFileName.substring(0, stdoutFileName.length() - 4) +
".err";
149 this.stderrFileName = stdoutFileName +
".err";
152 this.stderrFileName = null;
157 if (this.p != null) {
165 if (this.workingDirectory == null) {
166 if (this.cmd != null) {
167 this.p = Runtime.getRuntime().exec(this.cmd);
168 }
else if (this.cmdArgs != null) {
169 this.p = Runtime.getRuntime().exec(this.cmdArgs);
172 if (this.cmd != null) {
173 this.p = Runtime.getRuntime().exec(this.cmd, null,
new File(this.workingDirectory));
174 }
else if (this.cmdArgs != null) {
175 this.p = Runtime.getRuntime().exec(this.cmdArgs, null,
new File(this.workingDirectory));
179 BufferedReader in =
new BufferedReader(
new InputStreamReader(this.p.getInputStream()));
180 BufferedReader err =
new BufferedReader(
new InputStreamReader(this.p.getErrorStream()));
182 BufferedWriter writerIn = null;
183 StreamHandler outputHandler = null;
184 if (this.stdoutFileName != null) {
185 writerIn =
new BufferedWriter(
new FileWriter(this.stdoutFileName));
186 outputHandler =
new StreamHandler(in, writerIn);
187 outputHandler.start();
189 new BlackHoleStreamHandler(in).start();
191 BufferedWriter writerErr = null;
192 StreamHandler errorHandler = null;
193 if (this.stderrFileName != null) {
194 writerErr =
new BufferedWriter(
new FileWriter(this.stderrFileName));
195 errorHandler =
new StreamHandler(err, writerErr);
196 errorHandler.start();
198 new BlackHoleStreamHandler(err).start();
200 log.info(
"Starting external exe with command: " + (this.cmd != null ? this.cmd : Arrays.toString(
this.cmdArgs)));
201 log.info(
"Output of the externel exe is written to: " + this.stdoutFileName);
202 boolean processRunning =
true;
203 while (processRunning && !this.timeout) {
206 this.erg = this.p.exitValue();
207 log.info(
"external exe returned " + this.erg);
208 processRunning =
false;
209 }
catch (InterruptedException e) {
210 log.info(
"Thread waiting for external exe to finish was interrupted");
215 log.info(
"Timeout reached, killing process...");
218 if (outputHandler != null) {
220 outputHandler.join();
221 }
catch (InterruptedException e) {
222 log.info(
"got interrupted while waiting for outputHandler to die.", e);
225 if (errorHandler != null) {
228 }
catch (InterruptedException e) {
229 log.info(
"got interrupted while waiting for errorHandler to die.", e);
232 if (writerIn != null) {
236 if (writerErr != null) {
240 }
catch (IOException e) {
241 log.error(
"problem running exe", e);
247 static class BlackHoleStreamHandler
extends Thread {
248 private final BufferedReader in;
250 public BlackHoleStreamHandler(
final BufferedReader in) {
258 while ((line = this.in.readLine()) != null) {
260 }
catch (IOException e) {
261 log.info(
"StreamHandler got interrupted", e);
266 static class StreamHandler
extends Thread {
267 private final BufferedReader in;
268 private final BufferedWriter out;
270 public StreamHandler(
final BufferedReader in) {
271 this(in,
new BufferedWriter(
new OutputStreamWriter(System.out)));
274 public StreamHandler(
final BufferedReader in,
final PrintStream out) {
275 this(in,
new BufferedWriter(
new OutputStreamWriter(out)));
278 public StreamHandler(
final BufferedReader in,
final BufferedWriter out) {
287 while ((line = this.in.readLine()) != null) {
288 this.out.write(line);
289 this.out.write(
"\n");
292 }
catch (IOException e) {
293 log.info(
"StreamHandler got interrupted", e);
ExternalExecutor(final String cmd, final String stdoutFileName, final String workingDirectory)
static int run(final String cmd, final String stdoutFileName, final int timeout)
static int run(final String cmd, final String stdoutFileName, final int timeout, final String workingDirectory)
static int run(final String[] cmdArgs, final String stdoutFileName, final int timeout)
static int run(final String[] cmdArgs, final String stdoutFileName, final int timeout, final String workingDirectory)
static int waitForFinish(final ExternalExecutor myExecutor, final int timeout)
ExternalExecutor(final String[] cmdArgs, final String stdoutFileName, final String workingDirectory)