Java coincé dans une boucle infinie exécutant une commande wmic sur Windows Server 2003


J'essaie d'obtenir une liste des processus en cours d'exécution et de leurs chemins de fichiers sur une machine Windows Server 2003. J'utilise le code suivant pour essayer de le faire:

protected Map<String,String> getProcesses() {
    Map<String,String> processes = new HashMap<String,String>();
    try {
        String line;
        Process p = null;

        // Windows
        if (OS.indexOf("win") >= 0) {
            p = Runtime.getRuntime().exec("wmic process get description,executablepath");
            BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
            LOG.info("Entering while loop");
            while ((line = input.readLine()) != null) {
                LOG.info("blah");
                String[] array = line.split("\\s+");
                if (array.length > 1) {
                    processes.put(array[0], array[1]);
                }
            }
            LOG.info("Exited while loop");
            input.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return processes;
}

Le programme est bloqué dans une boucle infinie à la condition while. "blah" et "Exited while loop" ne sortent jamais dans le journal. J'ai exécuté la commande dans l'invite de commande à la fois sur ma machine locale win7 et sur le serveur qui génère très bien les informations. J'ai également exécuté le code ci-dessus sur ma machine locale qui fonctionne également bien. Il semble que ce soit un problème entre Java et Windows Server 2003 que je n'ai pas pu trouver au cours des 3 dernières heures de recherche sur Google. Toute aide serait très appréciée.

Author: lancex, 2012-11-13

2 answers

, Vous aurez besoin d'obtenir et de fermer votre OutputStream avant d'obtenir et d'utiliser votre InputStream. Cela confirmera au processus que vous avez commencé que vous avez fini d'envoyer une entrée (dans ce cas, aucune entrée) au processus.

p.getOutputStream().close();

Rappelez-vous que sur l'objet Process, l'entrée getInputStream() provient du flux de sortie du processus, et la sortie getOutputStream() va au flux d'entrée du processus.

 9
Author: rgettman, 2012-11-13 19:49:22

Rappelez-vous que l'opération BufferedReader.readLine() bloquera si la fin de l'entrée n'est pas atteinte, voir ici .

Je pense que ce que vous vivez est expliqué dans le API pour Process:

Les méthodes qui créent des processus peuvent ne pas fonctionner correctement pour les processus spéciaux sur certaines plates-formes natives, telles que les processus de fenêtrage natifs, les processus démon, les processus Win16/DOS sur Microsoft Windows ou les scripts shell. Le sous-processus créé n'a pas son propre terminal ou console. Toutes ses opérations d'e / s standard (c'est-à-dire stdin, stdout, stderr) seront redirigées vers le processus parent via trois flux (getOutputStream(), getInputStream(), getErrorStream()). Le processus parent utilise ces flux pour alimenter l'entrée et obtenir la sortie du sous-processus. Étant donné que certaines plates-formes natives ne fournissent qu'une taille de tampon limitée pour les flux d'entrée et de sortie standard, l'échec de l'écriture rapide du flux d'entrée ou de la lecture du flux de sortie du sous-processus peut entraîner d'un bloc, et même de blocage.

 2
Author: Jonathan Dixon, 2017-05-23 11:51:18