Perché il mio programma Java non riesce a leggere STDERR di Perl?
Domanda
Abbiamo un programma Perl per convalidare XML che viene richiamato da un programma Java. Non è in grado di scrivere sullo standard error e appeso in posizione di stampa.
Perl sta scrivendo STDERR e un programma Java è la lettura del STDERR utilizzando la funzione getErrorStream (). Ma il programma Perl è appeso a scrivere a STDERR. Ho il sospetto che la funzione Java sta bloccando il flusso STDERR completamente e Perl è in attesa di questo flusso per essere rilasciato.
C'è un modo in Perl per superare questo blocco e scrivere su standard error forza? Dal momento che Java sta facendo solo leggere l'API non dovrebbe essere il blocco del flusso STDERR come da java doc.
Codice Perl frammento è:
sub print_error
{
print STDERR shift;
}
frammento di codice Java è:
while ( getErrorStream() != null )
{
SOP errorMessage;
}
Apprezzare l'aiuto in anticipo.
Grazie, Mathew Liju
Soluzione
getErrorStream non lettura il flusso di errore, solo ottiene un handle ad esso. Come è un tubo, se non avete mai realmente leggerlo, si riempirà e forzare il programma Perl per bloccare.
Hai bisogno di qualcosa di simile:
Inputstream errors = getErrorStream();
while (errors.read(buffer) > 0) {
SOP buffer;
}
Altri suggerimenti
Idealmente, penso che per evitare situazione di stallo, in Java è necessario per deporre le uova thread separati per leggere lo STDERR e STDOUT. Suona come Perl sta bloccando quando si scrive su STDERR perché per un motivo o per l'altro non si è mai leggere da esso in Java.
Un ulteriore fattore da considerare è il buffer che si verifica con i processi di pipe.
Non v'è per impostazione predefinita, su un buffer di 30-line-ish che viene mantenuto dalla shell creando il tubo tra processi, quindi, se l'applicazione Perl non ha creato abbastanza dati, esso non sarà stato inviato a Java applicazione ancora da elaborare.
Può essere questa discussione ha una possibile causa per il vostro problema :
Aggiungi 3 righe all'inizio dello script Perl:
use IO::Handle;
STDOUT->autoflush(1);
STDERR->autoflush(1);
Il problema nel thread citato era legato a "come Perl sta memorizzando sua uscita".
Tuttavia qui, Adrian Pronk menziona nei commenti che "Perl è appeso perché Java non è mai leggendo la sua uscita ".
STDOUT->autoflush(1);
STDERR->autoflush(1);
Queste sono le informazioni di cui avevo bisogno!
Ho un'applicazione Java in esecuzione alcuni script Perl e mi piacerebbe solo ottenere l'uscita dopo che è stato completato.
Aggiungendo il autoflush(1)
ottengo subito.
A proposito, io ho thread separati per la lettura e STDERR
STDOUT
, e questo è la strada da percorrere.
Grazie.