Ich habe eine Klasse geschrieben, die allgemein externe (native) Programme aufrufen kann, aber nach einem definierten Timeout abbrechen soll. Doch beim testen (in meinem Fall mit 7-zip) erzeugt 7-zip viel output auf der console und die Verarbeitung wird nicht beendet. Ich vermute der StdInput der Anwendung muss geleert werden, da dieser voll ist!? Denn wenn ich den StdInput auslese ("clearStream(...)") kommt dieser Fehler nicht mehr. Doch dafür funktioniert der Timer dann nicht mehr.
Anbei die Klasse:
Anbei die Klasse:
Java:
package packager;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeoutException;
/**
*
*/
public class External2 {
private String fullCommand = null;
private long timeout = -1;
private ByteArrayOutputStream stdOutStream = null;
private ByteArrayOutputStream stdErrStream = null;
public External2( String command, String arguments, long timeout ) {
if( arguments!=null && !arguments.isEmpty() ) {
fullCommand = command.trim() + " " + arguments.trim();
} else {
fullCommand = command.trim();
}
this.timeout = timeout;
stdOutStream = new ByteArrayOutputStream();
stdErrStream = new ByteArrayOutputStream();
}
public int execute() throws ExecuteException, TimeoutException {
Timer timer = null;
if( timeout>0 ) {
System.out.println("[Timer] : " + timeout);
timer = new Timer();
timer.schedule( new InterruptTimer( Thread.currentThread() ), timeout );
}
Process process = null;
try {
process = Runtime.getRuntime().exec( fullCommand );
//comment the next 2 clearStreams to make timeout work
clearStream( process.getInputStream(), stdOutStream );
clearStream( process.getErrorStream(), stdErrStream );
process.waitFor();
return process.exitValue();
} catch( IOException e ) {
throw new ExecuteException( e );
} catch( InterruptedException e ) {
process.destroy();
throw new TimeoutException( e.getMessage() );
} finally {
if( timer != null ) {
timer.cancel();
}
}
}
private void clearStream( InputStream inputStream, OutputStream outputStream ) {
int i;
try {
while( (i = inputStream.read()) != -1 ) {
outputStream.write(i);
}
outputStream.flush();
} catch (IOException e) {//ignore
return;
}
}
private class InterruptTimer extends TimerTask {
private Thread threadToInterrupt = null;
public InterruptTimer( Thread threadToInterrupt) {
this.threadToInterrupt = threadToInterrupt;
}
@Override
public void run() {
threadToInterrupt.interrupt();
}
}
}
Zuletzt bearbeitet: