GNU/Linux >> Tutoriels Linux >  >> Linux

Java ProcessBuilder :blocages de processus résultants

Vous voulez le astuce ?

Ne démarrez pas votre processus à partir de ProcessBuilder.start() . N'essayez pas de jouer avec la redirection/consommation de flux depuis Java (surtout si vous ne vous en souciez pas ; )

Utilisez ProcessBuilder.start() pour lancer un petit script shell qui engloutit tous les flux d'entrée/sortie.

Quelque chose comme ça :

#!/bin/bash

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

C'est-à-dire :si vous ne vous souciez pas de stdout et que vous souhaitez toujours enregistrer stderr (n'est-ce pas ?) dans un fichier (error.log ici).

Si vous ne vous souciez même pas de stderr, redirigez-le simplement vers stdout :

#!/bin/bash

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

Et vous appelez ce petit script de Java, en lui donnant comme argument le nom du processus que vous souhaitez exécuter.

Si un processus exécuté sous Linux qui redirige à la fois stdout et stderr vers /dev/null produit toujours quelque chose alors vous avez une installation Linux cassée et non conforme ;)

En d'autres termes :le Just Works [TM] ci-dessus et débarrassez-vous du problème "vous devez consommer les flux dans ceci et dans cet ordre bla bla bla Java-spécifique non-sens" .


Si le processus écrit dans stderr ou stdout , et vous ne le lisez pas - il va simplement "se bloquer", bloquant lors de l'écriture dans stdout/err . Soit rediriger stdout/err à /dev/null en utilisant un shell ou une fusion stdout/err avec redirectErrorStream(true) et génère un autre thread qui lit à partir de stdout du processus


Le thread exécutant le processus peut se bloquer s'il ne gère pas la sortie. Cela peut être fait en créant un nouveau thread qui lit la sortie du processus.

    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. Comment démarrer la commande Linux en arrière-plan et détacher le processus dans le terminal

  2. Comment commencer à apprendre un langage de programmation

  3. Installer Java sur Ubuntu 20.04 LTS - Processus étape par étape ?

  4. Heure de début du processus avec fuseau horaire ?

  5. Comment démarrer un processus dans son propre groupe de processus ?

Option de machine virtuelle non reconnue MaxMetaspaceSize =256m - oxd-server n'a pas pu démarrer [Solution]

Démarrer un processus sur un autre téléscripteur ?

Utilisation croissante de la mémoire résidente (RSS) du processus Java

Impossible de démarrer le service postgresql sur CentOS 7

Comment puis-je déterminer quel processus en cours d'exécution utilise Java ?

Upstart :démarrer le service après un processus non-upstart