Lesen des streams (sdtout) eines externen Prozesses, der eine Exception wirft

Wie würde man bei einem Timeout denn das readline() überhaupt abbrechen? Den Thread einfach zu "killen" ist sicher keine gute Idee. Ist das Schließen des BufferedReaders eine sichere/korrekte Lösung? Dadurch müsste das readline() ja abgebrochen werden.
 
Hi.Warum beendest du dann nicht einfach den Prozeß?

Das ist natürlich auch eine Idee :) Ich glaube zwar, dass der Prozess automatisch beendet wird, wenn er die Exception wirft, aber einen Versuch ist es wert.

Ich denke, eine Möglichkeit wären auch noch die non-blocking IO methoden (package java.nio), das muss ich mal testen.
 
Das ist natürlich auch eine Idee :) Ich glaube zwar, dass der Prozess automatisch beendet wird, wenn er die Exception wirft, aber einen Versuch ist es wert.
Natürlich wird der Prozess beendet wenn eine Exception auftritt, die nicht behandelt wird. :confused:

Nochmal: den Timeout brauchst du nur falls das aufgerufene Programm nur dasitzt und nichts tut (also auch keine Exception wirft).

Ich frage mich wozu dieser ganze Aufwand gut sein soll. Wenn du eine Subroutine aufrufst bereitest du dich doch auch nicht darauf vor, das diese in eine Endlosschleife geraten könnte und du die Ausführung dann stoppen mußt...

Gruß
 
Nochmal: den Timeout brauchst du nur falls das aufgerufene Programm nur dasitzt und nichts tut (also auch keine Exception wirft).

Das ist so ja nicht ganz richtig. Das Kernproblem ist ja, dass ich stdout des externen Programmes sowie auch stderr lesen will. Dabei gibt es zwei Fälle:

1. Externes Programm gibt etwas auf stdout aus, das kann ich lesen. Danach versuche ich, vom stderr zu lesen, was blockiert und readline() kehrt nicht zurück.
2. Externes Programm wirft eine Exception. Ich versuche, vom stdout zu lesen, was nicht klappt. readline() blockiert und es geht nicht weiter.

Auf jeden Fall brauche ich entweder beim stdout-lesen oder stderr-lesen einen Timeout.



Ich frage mich wozu dieser ganze Aufwand gut sein soll. Wenn du eine Subroutine aufrufst bereitest du dich doch auch nicht darauf vor, das diese in eine Endlosschleife geraten könnte und du die Ausführung dann stoppen mußt...

Der Vergleich hinkt etwas - von einer externen Resource etwas über einen Stream zu lesen ist ja ne ganz andere Nummer, als eine Subroutine aufzurufen, die unter meiner vollen Kontrolle steht. Von der Unzuverlässigkeit einer Streaming-Kommunikation sollte man ausgehen, und das versuche ich hier ja gerade.

Ich denke man kann das ganze lösen, indem man entweder non-blocking-IO verwendet (NIO), oder eben das Lesen jeweils in 2 Threads macht - nach einem Timeout schließt man dann die Streams, was hoffentlich auch das readline() abbricht. Alternativ könnte man auch die Methode BufferedReader.ready() wiederholt aufrufen ("pollen"), und wenn das Ding nach z.B. 10 Versuchen nicht "ready" ist, bricht man die ganze Sache ab.
 
Das ist so ja nicht ganz richtig. Das Kernproblem ist ja, dass ich stdout des externen Programmes sowie auch stderr lesen will. Dabei gibt es zwei Fälle:

1. Externes Programm gibt etwas auf stdout aus, das kann ich lesen. Danach versuche ich, vom stderr zu lesen, was blockiert und readline() kehrt nicht zurück.
2. Externes Programm wirft eine Exception. Ich versuche, vom stdout zu lesen, was nicht klappt. readline() blockiert und es geht nicht weiter.

Auf jeden Fall brauche ich entweder beim stdout-lesen oder stderr-lesen einen Timeout.
Das ist Unsinn. Deine Annahme ist falsch das du etwas nacheinander machen mußt. Du kannst doch gleichzeitig von stderr und stdout lesen. Ich verstehe nicht wo da jetzt noch das Problem ist?! :confused:

Anscheinend hast du meinen Vorschlag noch nicht mal ausprobiert...
Der Vergleich hinkt etwas - von einer externen Resource etwas über einen Stream zu lesen ist ja ne ganz andere Nummer, als eine Subroutine aufzurufen, die unter meiner vollen Kontrolle steht. Von der Unzuverlässigkeit einer Streaming-Kommunikation sollte man ausgehen, und das versuche ich hier ja gerade.
Ich finde den Vergleich doch sehr passend. Was soll denn bei dieser Stream-Kommunikation unzuverlässig sein? Wenn es ein Problem gibt bekommst du eine Ausnahme - das gleiche kann auch beim Aufruf einer Subroutine geschehen.
Ich denke man kann das ganze lösen, indem man entweder non-blocking-IO verwendet (NIO), oder eben das Lesen jeweils in 2 Threads macht - nach einem Timeout schließt man dann die Streams, was hoffentlich auch das readline() abbricht. Alternativ könnte man auch die Methode BufferedReader.ready() wiederholt aufrufen ("pollen"), und wenn das Ding nach z.B. 10 Versuchen nicht "ready" ist, bricht man die ganze Sache ab.
Offenbar hast du ja schon eine akzeptable Lösung gefunden. Dann bau halt deinen unsinnigen Timeout ein.

Gruß
 
Nagut, wir wollen das mal nicht ausarten lassen :) Unsere Diskussion ging etwas aneinander vorbei; natürlich muss ich diese beiden Lesevorgänge nicht synchron machen, sondern via eines Threads asynchron ablaufen lassen. Meine beiden Fälle oben sollten auch etwas anderes signalisieren. Aber lass uns den Teil nun abschließen - ich bin Dir dankbar, dass Du so oft geantwortet hast, das kostet ja schließlich Zeit.

Offenbar hast du ja schon eine akzeptable Lösung gefunden. Dann bau halt deinen unsinnigen Timeout ein.

Hier würde ich allerdings nochmal gerne nachhaken, vielleicht habe ich ja etwas nicht verstanden. Fakt ist doch, dass das readline() blockiert und nicht zurückkehrt, wenn auf dem Stream nichts kommt und dass das externe Programm, wenn es eine Exception wirft, den Stream nicht schließt. Ich habe es ausprobiert, eines der beiden readlines() (auch wenn sie parallel ablaufen), kehren nicht zurück und blockieren.

Wenn diese Aussagen so stimmen, dann muss man doch einen Timeout haben, um das readline() irgendwie zu "killen". Oder was würdest Du machen, wenn readline() blockiert?
 
Fakt ist doch, dass das readline() blockiert und nicht zurückkehrt, wenn auf dem Stream nichts kommt und dass das externe Programm, wenn es eine Exception wirft, den Stream nicht schließt. Ich habe es ausprobiert, eines der beiden readlines() (auch wenn sie parallel ablaufen), kehren nicht zurück und blockieren.
Dann zeig diesen Code (bzw. mach ein Minimalbeispiel bei dem dieser Fehler auftritt).

Sobald die Streams geschlossen werden (und das passiert immer sobald das Programm beendet ist), geben beide readline() Aufrufe null zurück.

Wie gesagt, falls das aufgerufene Programm so grottig schlecht geschrieben ist, dass es nach einer Exception einfach weiterarbeitet und dabei nichts sinnvolles mehr macht, und du das Programm auch nicht berichtigen kannst, dann wäre ein Timeout durchaus sinnvoll.

Gruß
 
Zurück