GNU/Linux >> Linux Esercitazione >  >> Linux

Java ProcessBuilder:il processo risultante si blocca

Vuoi il trucco?

Non avviare il processo da ProcessBuilder.start() . Non cercare di interferire con il reindirizzamento/consumo di stream da Java (soprattutto se non te ne frega niente; )

Usa ProcessBuilder.start() per avviare un piccolo script di shell che fagocita tutti i flussi di input/output.

Qualcosa del genere:

#!/bin/bash

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

Cioè:se non ti interessa stdout e vuoi comunque registrare stderr (vero?) in un file (error.log qui).

Se non ti interessa nemmeno stderr, reindirizzalo a stdout:

#!/bin/bash

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

E chiami quel minuscolo script da Java, dandogli come argomento il nome del processo che vuoi eseguire.

Se un processo in esecuzione su Linux che reindirizza sia stdout che stderr a /dev/null continua a produrre qualsiasi cosa allora hai un'installazione di Linux non funzionante e non conforme;)

In altre parole:quanto sopra Just Works [TM] e sbarazzarsi del problematico "devi consumare i flussi in questo e quell'ordine bla bla bla non-senso specifico di Java" .


Se il processo scrive in stderr o stdout , e non lo stai leggendo - semplicemente "si bloccherà", bloccando quando scrivi su stdout/err . Reindirizza stdout/err a /dev/null usando una shell o unendo stdout/err con redirectErrorStream(true) e genera un altro thread che legge da stdout del processo


Il thread che esegue il processo potrebbe bloccarsi se non gestisce l'output. Questo può essere fatto generando un nuovo thread che legge l'output del processo.

    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. Installa Oracle Java 16 su Ubuntu 18.04 / 20.04 / 21.04 - Un processo passo dopo passo?

  2. Avviare un processo su un Tty diverso?

  3. Come avviare un processo nel proprio gruppo di processi?

  4. Uccidi un processo Java (in Linux) in base al nome del processo anziché al PID

  5. Crescente utilizzo della memoria residente (RSS) di Java Process

Ora di inizio del processo con fuso orario?

script linux per terminare il processo java

Come posso determinare quale processo in esecuzione utilizza java?

Come ordinare l'output di ps in base all'ora di inizio del processo?

Come configuro monit per avviare un processo con un utente specifico?

Linux - Come posso vedere quando è iniziato un processo?