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
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