* @throws ForkedCommandException if process execution fails for some reason
* or if the timeout has expired and the process was killed
*/
public int execute(int timeout) {
if (null == arguments || arguments.length == 0) {
throw new ForkedCommandException(new Message("NO_ARGUMENTS_EXC", LOG));
}
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("Executing command: " + this);
}
try {
Runtime rt = Runtime.getRuntime();
if (environment == null) {
proc = rt.exec(arguments);
} else {
StringBuffer msg = null;
if (LOG.isLoggable(Level.FINE)) {
msg = new StringBuffer();
msg.append("Process environment: ");
for (int i = 0; i < environment.length; i++) {
msg.append(environment[i]);
msg.append(" ");
}
LOG.fine(msg.toString());
}
proc = rt.exec(arguments, environment);
}
} catch (IOException ex) {
throw new ForkedCommandException(new Message("EXECUTE_EXC", LOG, this), ex);
}
// catch process stderr/stdout
ForkedCommandStreamHandler cmdOut = new ForkedCommandStreamHandler(proc.getInputStream(),
outputStream == null
? System.out : outputStream);
ForkedCommandStreamHandler cmdErr = new ForkedCommandStreamHandler(proc.getErrorStream(),
errorStream == null
? System.err : errorStream);
cmdErr.start();
cmdOut.start();
// now wait for the process on our own thread
start();
// kill process after timeout
try {
if (timeout > 0) {
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("Waiting " + timeout + " seconds for process to complete");
}
join(timeout * 1000);
} else {
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("Waiting for process to complete");
}
join();
}
} catch (InterruptedException ex) {
ex.printStackTrace();
} finally {
if (completed) {
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("Process completed in time");
}
} else {
proc.destroy();
killed = true;
LOG.fine("Process timed out and was killed");
}
// wait for the streams threads to finish if necessary
if (joinErrOut) {
if (LOG.isLoggable(Level.FINE)) {
LOG.info("Waiting a further 10 seconds for process "
+ " stdout/stderr streams to be flushed");
}
try {
cmdErr.join(10 * 1000);
cmdOut.join(10 * 1000);
} catch (InterruptedException ex) {
// silently ignore
}
}
}
if (killed) {
throw new ForkedCommandException(new Message("TIMEOUT_EXC", LOG, timeout));
}
int exitVal = proc.exitValue();
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("Process exited with value: " + exitVal);
}