Process.waitFor() nunca regresa
Process process = Runtime.getRuntime().exec("tasklist");
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
process.waitFor();
Hay muchas razones por las que waitFor()
no regresa.
Pero normalmente todo se reduce al hecho de que el comando ejecutado no se cierra.
Esto, nuevamente, puede deberse a muchas razones.
Una razón común es que el proceso produce algún resultado y no se lee en las secuencias apropiadas. Esto significa que el proceso se bloquea tan pronto como el búfer está lleno y espera a que su proceso continúe leyendo. Su proceso, a su vez, espera a que finalice el otro proceso (lo cual no sucederá porque espera a su proceso,...). Ésta es una situación clásica de punto muerto.
Debe leer continuamente el flujo de entrada del proceso para asegurarse de que no se bloquee.
Hay un buen artículo que explica todos los errores Runtime.exec()
y muestra cómo solucionarlos llamado "Cuando Runtime.exec() no funciona" (sí, el artículo es del año 2000, ¡pero el contenido aún se aplica!)
Parece que no estás leyendo el resultado antes de esperar a que finalice. Esto está bien sólo si la salida no llena el búfer. Si es así, esperará hasta que lea el resultado, catch-22.
Quizás tengas algunos errores que no estás leyendo. Esto haría que la aplicación se detuviera y esperara para siempre. Una forma sencilla de solucionar este problema es redirigir los errores a la salida normal.
ProcessBuilder pb = new ProcessBuilder("tasklist");
pb.redirectErrorStream(true);
Process process = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null)
System.out.println("tasklist: " + line);
process.waitFor();
También del documento Java:
java.lang
Proceso de clase
Debido a que algunas plataformas nativas solo proporcionan un tamaño de búfer limitado para los flujos de entrada y salida estándar, no escribir rápidamente el flujo de entrada o leer el flujo de salida del subproceso puede provocar que el subproceso se bloquee e incluso se bloquee.
No borrar el búfer del flujo de entrada (que canaliza al flujo de salida del subproceso) del proceso puede provocar el bloqueo del subproceso.
Prueba esto:
Process process = Runtime.getRuntime().exec("tasklist");
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((reader.readLine()) != null) {}
process.waitFor();
Me gustaría agregar algo a las respuestas anteriores, pero como no tengo representante para comentar, simplemente agregaré una respuesta. Esto está dirigido a usuarios de Android que programan en Java.
Según la publicación de RollingBoy, este código casi funcionó para mí:
Process process = Runtime.getRuntime().exec("tasklist");
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((reader.readLine()) != null) {}
process.waitFor();
En mi caso, waitFor() no se liberó porque estaba ejecutando una declaración sin retorno ("ip adddr flush eth0"). Una manera fácil de solucionar este problema es simplemente asegurarse de devolver siempre algo en su estado de cuenta. Para mí, eso significó ejecutar lo siguiente: "ip adddr flush eth0 && echo done". Puede leer el búfer todo el día, pero si nunca se devuelve nada, su hilo nunca liberará su espera.
¡Espero que ayude a alguien!
Hay varias posibilidades:
- No ha consumido todo el resultado del proceso
stdout
. - No ha consumido todo el resultado del proceso
stderr
. - El proceso está esperando su opinión y usted no la ha proporcionado o no ha cerrado el proceso
stdin
. - El proceso gira en un bucle cerrado.