PDA

View Full Version : [JAVA] Process exec


LimiT-MaTz
16-05-2009, 09:59
Buongiorno,

vi spiego brevemente quello che vorrei realizzare.
ho un programma 'X' (testuale) da cui devo raccogliere l'output da un programma java.
il programma 'X' non è oneshot ma rimane in esecuzione finchè non lo killo ( è uno sniffer ).

Mi interesserebbe creare un wrapper in java che mi permettesse tramite 2 metodi di eseguire il programma:
public void start() => fa partire il programma
public void stop() => ferma l'esecuzione e ritorna l'output ( stdout o eccezzione nel caso vi sia stata un return != 0 quando ho fatto partire il programma).

Il tutto dovrebbe essere eseguito su un Thread.

Ora vi espongo quanto realizzato e i problemi riscontrati.
Leggendo la doc ho trovato la funzione exec che mi permette di eseguire su un Thread un 'programma' e di avere a disposizione i 3 stream (stdin stdout stderr) .
perfetto, non mi sembra neanche vero, è quello che fa al caso mio.

nel metodo start() => faccio partire la exec.
nel metodo stop() => verifico che il processo creato non sia uscito. Se è uscito sarà probabilmente un errore altrimenti se è ancora in esecuzione non ci sono problemi.Fatte queste considerazioni mi verrebbe l'idea di prendermi l'stdout o stderr ( dipende da exit ) e leggerne il contenuto e sucessivamente invocare una proc.destroy() ( per killare il processo ).

Ecco che spuntano i problemi, quando chiamo la stop, nello stream (stdout) non trovo nulla. Come se il programma non avesse scritto nulla in output ( cosa non vera ).

La cosa interessante è che cambio programma con uno oneshot (esempio ls) il sistema funziona. Mi è venuto il dubbio che i dati fossero disponibili solo quando il processo è terminato.Allora ho provato a terminare il processo con destroy, ma cosi' facendo perdo anche gli stream.

vi incollo il codice per essere piu' chiaro

public void start(){
try{
ProcessBuilder pb = new ProcessBuilder(binpath);
proc = pb.start();

}
catch (IOException e)
{
System.err.println("exec error: " + e);
}
}
public String terminate(){
String result = "";
int exit = 0;
try
{
exit = proc.exitValue();
}
catch (IllegalThreadStateException e) {
exit = 0;
}
if(exit == 0){
InputStream in = proc.getInputStream();
result = convertStreamToString(in);
System.out.println(result);
proc.destroy();
}
else{
InputStream in = proc.getErrorStream();
System.out.println(convertStreamToString(in));
throw new RuntimeException();
}
return result;
}
public String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();

String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}

}



avreste qualche consiglio da darmi? grazie