Important when you pass in System.out/System.err or want to do something special to stream after processing. Submitted By: Darrell DeBoer <darrell@apache.org> git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271649 13f79535-47bb-0310-9956-ffa450edef68master
@@ -115,7 +115,7 @@ public class DefaultExecManager | |||||
final CommandLauncher launcher = getLauncher( command ); | final CommandLauncher launcher = getLauncher( command ); | ||||
final Process process = launcher.exec( command ); | final Process process = launcher.exec( command ); | ||||
final ProcessMonitor monitor = | final ProcessMonitor monitor = | ||||
new ProcessMonitor( process, input, output, error, timeout ); | |||||
new ProcessMonitor( process, input, output, error, timeout, false ); | |||||
final Thread thread = new Thread( monitor, "ProcessMonitor" ); | final Thread thread = new Thread( monitor, "ProcessMonitor" ); | ||||
thread.start(); | thread.start(); | ||||
@@ -19,6 +19,7 @@ import org.apache.aut.nativelib.ExecManager; | |||||
import org.apache.aut.nativelib.ExecMetaData; | import org.apache.aut.nativelib.ExecMetaData; | ||||
import org.apache.aut.nativelib.Os; | import org.apache.aut.nativelib.Os; | ||||
import org.apache.avalon.excalibur.util.StringUtil; | import org.apache.avalon.excalibur.util.StringUtil; | ||||
import org.apache.avalon.excalibur.io.IOUtil; | |||||
/** | /** | ||||
* This is the class that can be used to retrieve the environment | * This is the class that can be used to retrieve the environment | ||||
@@ -157,13 +158,17 @@ final class Environment | |||||
final ExecMetaData metaData = new ExecMetaData( command, null, workingDirectory ); | final ExecMetaData metaData = new ExecMetaData( command, null, workingDirectory ); | ||||
final ByteArrayOutputStream output = new ByteArrayOutputStream(); | final ByteArrayOutputStream output = new ByteArrayOutputStream(); | ||||
final int retval = m_execManager.execute( metaData, null, output, output, 0 ); | |||||
if( retval != 0 ) | |||||
{ | |||||
// Just try to use what we got | |||||
} | |||||
try { | |||||
final int retval = m_execManager.execute( metaData, null, output, output, 0 ); | |||||
if( retval != 0 ) | |||||
{ | |||||
// Just try to use what we got | |||||
} | |||||
return output.toString(); | |||||
return output.toString(); | |||||
} finally { | |||||
IOUtil.shutdownStream( output ); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
@@ -72,11 +72,33 @@ class ProcessMonitor | |||||
*/ | */ | ||||
private final OutputStream m_error; | private final OutputStream m_error; | ||||
/** | |||||
* Specifies whether the monitor should shutdown | |||||
* input, output and error Streams when it finishes execution. | |||||
* This should be set to <code>true</code> for processes which | |||||
* will run asynchronously. | |||||
*/ | |||||
private final boolean m_shutdownStreams; | |||||
/** | |||||
* Creates a monitor for a given {@link java.lang.Process}, which pipes | |||||
* input from the given input stream to the process, and pipes the process | |||||
* output to the given OutputStreams. | |||||
* | |||||
* @param process the Process to be monitored | |||||
* @param input is read into the Process' stdin | |||||
* @param output receives the Process' stdout | |||||
* @param error receives the Process' stderr | |||||
* @param timeoutDuration how long to let the Process run before killing it. | |||||
* @param shutdownStreams specifies if the monitor should shutdown the | |||||
* streams when the Process exits. | |||||
*/ | |||||
public ProcessMonitor( final Process process, | public ProcessMonitor( final Process process, | ||||
final InputStream input, | final InputStream input, | ||||
final OutputStream output, | final OutputStream output, | ||||
final OutputStream error, | final OutputStream error, | ||||
final long timeoutDuration ) | |||||
final long timeoutDuration, | |||||
final boolean shutdownStreams ) | |||||
{ | { | ||||
if( null == process ) | if( null == process ) | ||||
{ | { | ||||
@@ -100,6 +122,7 @@ class ProcessMonitor | |||||
m_output = output; | m_output = output; | ||||
m_error = error; | m_error = error; | ||||
m_timeout = timeout; | m_timeout = timeout; | ||||
m_shutdownStreams = shutdownStreams; | |||||
} | } | ||||
/** | /** | ||||
@@ -139,9 +162,20 @@ class ProcessMonitor | |||||
//that we have got all the data | //that we have got all the data | ||||
processStreams(); | processStreams(); | ||||
IOUtil.shutdownStream( m_input ); | |||||
IOUtil.shutdownStream( m_output ); | |||||
IOUtil.shutdownStream( m_error ); | |||||
cleanupStreams(); | |||||
} | |||||
/** | |||||
* Utility method which cleans up all IO Streams, if required. | |||||
*/ | |||||
private void cleanupStreams() | |||||
{ | |||||
if( m_shutdownStreams ) | |||||
{ | |||||
IOUtil.shutdownStream( m_input ); | |||||
IOUtil.shutdownStream( m_output ); | |||||
IOUtil.shutdownStream( m_error ); | |||||
} | |||||
} | } | ||||
/** | /** | ||||