Constructors Summary |
---|
public ProcessExecutor(String[] cmd)Creates new ProcessExecutor
this(cmd, DEFAULT_TIMEOUT_SEC, null);
|
public ProcessExecutor(String[] cmd, String[] inputLines)Creates new ProcessExecutor
this(cmd, DEFAULT_TIMEOUT_SEC, inputLines);
|
public ProcessExecutor(String[] cmd, long timeoutSeconds)Creates new ProcessExecutor
this(cmd, timeoutSeconds, null);
|
public ProcessExecutor(String[] cmd, long timeoutSeconds, String[] inputLines)
this(cmd, timeoutSeconds, inputLines, null, null);
|
public ProcessExecutor(String[] cmd, long timeoutSeconds, String[] inputLines, String[] env, File workingDir)Creates a new ProcessExecutor that executes the given
command.
mCmdStrings = cmd;
mInputLines = inputLines;
mEnv = env;
mWorkingDir = workingDir;
char fwdSlashChar = '/";
char backSlashChar = '\\";
if (System.getProperty("Debug") != null) {
// turn on debug, this option was added to help developers
// debug the their code
bDebug=true;
}
for(int i=0; i<mCmdStrings.length; i++)
{
if (OS.isUnix())
{
mCmdStrings[i] = mCmdStrings[i].replace(backSlashChar, fwdSlashChar);
}
else
{
mCmdStrings[i] = mCmdStrings[i].replace(fwdSlashChar, backSlashChar);
}
}
mTimeoutMilliseconds = (long) timeoutSeconds * 1000;
|
Methods Summary |
---|
private java.lang.String | a2s(java.lang.String[] a)
final StringBuffer s = new StringBuffer();
if (a != null) {
for (int i = 0 ; i < a.length ; i++) {
s.append(a[i]);
s.append(" ");
}
}
return ( s.toString() );
|
private void | addInputLinesToProcessInput(java.lang.Process subProcess)
if(mInputLines==null)
return;
PrintWriter out = null;
try
{
out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(subProcess.getOutputStream())));
for(int i=0; i<mInputLines.length; i++)
{
if(bDebug) {
System.out.println("InputLine ->" + mInputLines[i] + "<-");
}
out.println(mInputLines[i]);
}
out.flush();
}
catch (Exception e)
{
throw new ExecException(e.getMessage());
}
finally
{
try
{
out.close();
}
catch (Throwable t)
{
}
}
|
private static final java.lang.String | cannotCreateTempFiles()
return "Could not create temporary files - check "
+ System.getProperty("java.io.tmpdir")
+ " to see if its writeable and not-full";
|
private boolean | debug()
final String td = System.getProperty("java.io.tmpdir");
final String n = "as_debug_process_executor"; // a debug hook
final File f = new File(td, n);
return ( f.exists() );
|
private void | deleteTempFiles()
if (mOutStream != null) {
try {
mOutStream.flush();
mOutStream.close();
} catch (IOException ioe) {
// Ignore
}
}
if (mErrStream != null) {
try {
mErrStream.flush();
mErrStream.close();
} catch (IOException ioe) {
// Ignore
}
}
if (mOutFile != null) mOutFile.delete();
if (mErrFile != null) mErrFile.delete();
|
public void | execute()
execute(false);
|
public java.lang.String[] | execute(boolean bReturnOutputLines)
return execute(bReturnOutputLines, true);
|
public java.lang.String[] | execute(boolean bReturnOutputLines, boolean bStartUpTimeLimit)
init();
InputStream inputStream = null;
try
{
if (bDebug) {
System.out.println("\n**** Executing command:");
for(int ii=0; ii < mCmdStrings.length; ii++) {
System.out.println(mCmdStrings[ii]);
}
}
mSubProcess = Runtime.getRuntime().exec(mCmdStrings, mEnv, mWorkingDir);
if(mInputLines != null)
addInputLinesToProcessInput(mSubProcess);
if(!bReturnOutputLines)
mOutStream = redirectProcessOutput(mSubProcess);
else
inputStream = mSubProcess.getInputStream(); //attach to input stream for later reading
mErrStream = redirectProcessError(mSubProcess);
// see if process should startup in a limited ammount of time
// processes used by ProcessManager don't return
if (bStartUpTimeLimit) {
long timeBefore = System.currentTimeMillis();
boolean timeoutReached = false;
boolean isSubProcessFinished = false;
boolean shouldBeDone = false;
while (! shouldBeDone)
{
sleep(kSleepTime);
long timeAfter = System.currentTimeMillis();
timeoutReached = (timeAfter - timeBefore) >= mTimeoutMilliseconds;
try
{
mExitValue = mSubProcess.exitValue();
isSubProcessFinished = true;
}
catch(IllegalThreadStateException itse)
{
isSubProcessFinished = false;
//ignore exception
}
shouldBeDone = timeoutReached || isSubProcessFinished;
}
if (!isSubProcessFinished)
{
mSubProcess.destroy();
mExitValue = -255;
throw new ExecException("Subprocess timed out after "+mTimeoutMilliseconds +"mS");
}
else
{
mExitValue = mSubProcess.exitValue();
if (debug()) {
System.out.println("Subprocess command line = " + a2s(mCmdStrings));
System.out.println("Subprocess exit value = " + mExitValue);
}
if (mExitValue != 0)
{
mExitValue = mSubProcess.exitValue();
if (mExitValue != 0)
{
throw new ExecException(getExceptionMessage());
}
}
}
}
}
catch(SecurityException se)
{
throw new ExecException(se.getMessage());
}
catch(IOException ioe)
{
throw new ExecException(ioe.getMessage());
}
finally {
// retain buffers before deleting them
retainBuffers();
// only delete files if the time is limited
// for processes that don't return, the temp files will remain
if (bStartUpTimeLimit) {
deleteTempFiles();
}
}
if(bReturnOutputLines) {
return getInputStrings(inputStream);
} else {
return null;
}
|
protected java.lang.String | getExceptionMessage()Allows a subclass to control the error message returned when a non-zero exit code is
returned from a failed execution
/* read the error message from error file */
String errorMessage = getFileBuffer(mErrFile);
if (errorMessage.length() == 0) {
errorMessage = "The Process Output: " + getLatestOutput(mOutFile);
}
return "abnormal subprocess termination: Detailed Message:" + errorMessage;
|
public boolean | getExecutionRetentionFlag()
return ( this.retainExecutionLogs );
|
protected java.lang.String | getFileBuffer(java.io.File file)Returns the contents of a file as a String. It never returns a null. If
the file is empty, an empty string is returned.
final StringBuffer sb = new StringBuffer();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append(NEWLINE);
}
}
catch(Exception e) {
//squelch the exception
}
finally {
try {
reader.close();
}
catch(Exception e) {}
}
return ( sb.toString() );
|
private java.lang.String[] | getInputStrings(java.io.InputStream inputStream)
if(inputStream==null)
return null;
BufferedReader in = null;
ArrayList list = new ArrayList();
String str;
try
{
in = new BufferedReader( new InputStreamReader(inputStream));
while((str=in.readLine())!=null)
list.add(str);
if(list.size()<1)
return null;
return (String[])list.toArray(new String[list.size()]);
}
catch (Exception e)
{
throw new ExecException(e.getMessage());
}
finally
{
try
{
in.close();
}
catch (Throwable t)
{
}
}
|
public java.lang.String | getLastExecutionError()Returns the last LAST_BYTES bytes in the error stream of last execution as a String, if
the ProcessExecutor was configured properly. It may return null if the
retentionFlag is set to false.
return ( this.lastExecutionErrorString );
|
public java.lang.String | getLastExecutionOutput()Returns the last LAST_BYTES bytes in the output stream of last execution as a String, if
the ProcessExecutor was configured properly. It may return null if the
retentionFlag is set to false.
return ( this.lastExecutionOutputString );
|
protected java.lang.String | getLatestOutput(java.io.File f)
return ( new RAFileReader(f).readLastBytesAsString() );
|
public int | getProcessExitValue()Get the exit value of the process executed. If this method is called
before process execution is complete (i.e. before execute() method has
returned, it will return -1. If sub process is terminated at timeout,
the method will return -255
return mExitValue;
|
public java.lang.Process | getSubProcess()
return mSubProcess;
|
private void | init()
try{
mOutFile = File.createTempFile("stdout", null);
mOutFile.deleteOnExit();
mErrFile = File.createTempFile("stderr", null);
mErrFile.deleteOnExit();
}
catch (IllegalArgumentException iae){
deleteTempFiles();
throw new ExecException("Internal error (util.ProcessExecutor.init()): "+iae.getMessage());
}
catch (IOException ioe){
deleteTempFiles();
throw new ExecException(cannotCreateTempFiles());
}
|
public static void | main(java.lang.String[] args)
testProcessError();
|
private java.io.OutputStream | redirectProcessError(java.lang.Process subProcess)
OutputStream out = null;
try
{
InputStream in = subProcess.getErrorStream();
// Redirect stderr for verbose mode
if(mVerboseMode) {
// send output to stderr
out=System.err;
} else {
// send to temp file
out=new FileOutputStream(mErrFile);
}
new FlusherThread(in, out).start();
}
catch (Exception e)
{
throw new ExecException(e.getMessage());
}
return out;
|
private java.io.OutputStream | redirectProcessOutput(java.lang.Process subProcess)
OutputStream out = null;
try
{
InputStream in = subProcess.getInputStream();
// Redirect stderr for verbose mode
if(mVerboseMode) {
// send output to stderr
out=System.err;
} else {
// send to temp file
out=new FileOutputStream(mOutFile);
}
new FlusherThread(in, out).start();
}
catch (Exception e)
{
throw new ExecException(e.getMessage());
}
return out;
|
public void | retainBuffers()
if (this.retainExecutionLogs) {
this.lastExecutionErrorString = this.getLatestOutput(this.mErrFile);
this.lastExecutionOutputString = this.getLatestOutput(this.mOutFile);
}
|
public void | setExecutionRetentionFlag(boolean s)This is the setting after the fact that an instance of ProcessExecutor
is created. This is to be used in case the output and error of the last
execute call has to be retained for latter analysis.
this.retainExecutionLogs = s;
|
public void | setVerbose(boolean verbose)
mVerboseMode=verbose;
|
private void | sleep(long millis)
try
{
Thread.sleep(millis);
}
catch(InterruptedException ie)
{
//ignore exception
}
|
private static void | testProcessError()
ProcessExecutor executor = new ProcessExecutor(
new String[]{"/usr/bin/ls", "-wrongPARAMS123"});
try {
executor.execute();
}
catch (ExecException ee) {
System.out.println(ee.getMessage());
}
|