GNU/Linux >> Tutoriales Linux >  >> Linux

Java ProcessBuilder:el proceso resultante se cuelga

Quieres el ¿truco?

No inicie su proceso desde ProcessBuilder.start() . No intente meterse con la redirección/consumo de transmisión de Java (especialmente si no le importa nada;)

Utilice ProcessBuilder.start() para iniciar un pequeño script de shell que engulle todos los flujos de entrada/salida.

Algo así:

#!/bin/bash

nohup $1 >/dev/null 2>error.log &

Es decir:si no le importa la salida estándar y aún desea registrar stderr (¿o sí?) en un archivo (error.log aquí).

Si ni siquiera te importa stderr, simplemente redirígelo a stdout:

#!/bin/bash

nohup $1 >/dev/null 2>1 &

Y llamas a ese pequeño script desde Java, dándole como argumento el nombre del proceso que quieres ejecutar.

Si un proceso que se ejecuta en Linux que está redirigiendo tanto stdout como stderr a /dev/null todavía produce cualquier cosa entonces tienes una instalación de Linux rota, no compatible;)

En otras palabras:lo anterior Just Works [TM] y deshacerse del problemático "necesitas consumir las secuencias en este y aquel orden bla bla bla sin sentido específico de Java" .


Si el proceso escribe en stderr o stdout , y no lo estás leyendo; simplemente se "colgará", bloqueándose al escribir en stdout/err . Redireccionar stdout/err a /dev/null usando un shell o fusionar stdout/err con redirectErrorStream(true) y genere otro hilo que lea desde stdout del proceso


El subproceso que ejecuta el proceso puede bloquearse si no maneja la salida. Esto se puede hacer generando un nuevo hilo que lea el resultado del proceso.

    final ProcessBuilder builder = new ProcessBuilder("script")
                    .redirectErrorStream(true)
                    .directory(workDirectory);

    final Process process = builder.start();
    final StringWriter writer = new StringWriter();

    new Thread(new Runnable() {
        public void run() {
            IOUtils.copy(process.getInputStream(), writer);
        }
    }).start();

    final int exitValue = process.waitFor();
    final String processOutput = writer.toString();

Linux
  1. Cómo iniciar el comando de Linux en segundo plano y separar el proceso en la terminal

  2. Instalar Java en Ubuntu 20.04 LTS - ¿Proceso paso a paso?

  3. Instalar Java en el sistema Debian 9 - ¿Proceso paso a paso?

  4. ¿Iniciar un proceso en un Tty diferente?

  5. script de linux para matar el proceso java

Cómo empezar a aprender un lenguaje de programación

Instale Oracle Java 16 en Ubuntu 18.04/20.04/21.04:¿un proceso paso a paso?

Opción de VM no reconocida MaxMetaspaceSize=256m – oxd-server no pudo iniciarse [Solución]

¿Hora de inicio del proceso con zona horaria?

¿Cómo iniciar un proceso en su propio grupo de procesos?

Creciente uso de memoria residente (RSS) de Java Process