2009-05-06 10 views
1

J'ai une classe qui gère la création de documents RTF et une méthode dans cette classe qui appelle l'éditeur RTF avec un fichier XML pour l'affichage.Exécuteur d'exécution et éditeur RTF personnalisé

Tous les utilisateurs, sauf un, peuvent accéder à cet éditeur sans problème. Cet utilisateur rencontre systématiquement un problème où son application se bloque. Il n'y a pas d'erreurs dans les journaux. Normalement ce genre de problème est facilement identifié, reproduit et corrigé, cependant, je ne peux pas pour la vie de ma reproduire ainsi mes tentatives de débogage échouent.

Fondamentalement, le code est le suivant:

int exitVal = CUBSRTFEditor.runRTFEditor("c:\\tmp\\control"+ap_doc_id+".xml", xml,"I:\\AppealsLetters.exe /process \"c:\\tmp\\control"+ap_doc_id+".xml\""); 

public static int runRTFEditor(String xmlLocation, String xmlContent, String executePath) 
{ 
    int exitVal = 0; 
    createLocalFile(xmlLocation, xmlContent); 

    try 
    { 
     System.out.println("executePath must = "+executePath); 
     Runtime rt = Runtime.getRuntime(); 
     Process proc = rt.exec(executePath); 
     System.out.println("after executePath runs"); 

     //exhaust that stream before waiting for the process to exit 
     InputStream inputstream = proc.getInputStream(); 
     InputStreamReader inputstreamreader = new InputStreamReader(inputstream); 
     BufferedReader bufferedreader = new BufferedReader(inputstreamreader); 
     // read the ls output 
     String line; 
     while ((line = bufferedreader.readLine())!= null) 
     { 
      System.out.println(line); 
     } 
     exitVal = proc.waitFor(); 
    } 
    catch (Throwable t) 
    { 
     t.printStackTrace(); 
    } 

    CUBSRTFEditor.deleteTempFile(xmlLocation); 

    return exitVal; 
} 

La dernière sortie est la première System.out. Quand je prends le fichier xml et l'exécute sur n'importe quel autre PC, il s'exécute sans problème. Je ne vois aucune information utile dans proc.getErrorStream() ou proc.getOutputStream().

La documentation Javadoc de JDK sur ce problème (suspendu exec): Parce que certaines plates-formes natives ne fournissent que la taille de la mémoire tampon limitée pour les flux d'entrée et sortie standard, le défaut d'écrire rapidement le flux d'entrée ou de lire le flux de sortie du sous-processus peut provoquer le sous-processus à bloquer, et même l'interblocage.

J'essaie épuiser ce courant avant d'attendre le processus pour quitter et cela ne semble pas aider car il semble ne jamais arriver à ce point (la deuxième System.out n'est pas affiché)

Ai-je mis en œuvre ceci incorrectement? Est-ce que je manque quelque chose d'important? Toutes les idées sur la façon d'obtenir plus d'informations sur le processus serait génial.

Je suis coincé ....

Répondre

2

Runtime.exec() est un peu Spud faussement méchant de travailler avec. J'ai trouvé this article (vieux, mais toujours pertinent) pour être très utile. Vous pouvez toujours passer à la page 4 pour obtenir un exemple de code hautement gankable. :-)

D'un coup d'œil, votre code doit gérer à la fois proc.getOutputStream() et proc.getErrorStream(), ce qui est une bonne raison pour gérer ces flux dans des threads séparés.

+0

+1 pour le lien. C'est un super lien et je l'ai déjà lu deux fois d'avant en arrière. C'était utile mais n'a pas vraiment aidé. J'ai ajouté le proc.getOutputStream() mais toujours pas de chance. – northpole

+0

Voir ma réponse modifiée; vous devez également cliquer sur proc.getErrorStream(). De préférence dans leurs propres fils individuels. – BlairHippo

0

Je voulais mettre à jour cela parce que le changement est entré dans la production aujourd'hui et a fonctionné. Basé sur les suggestions de BlairHippo je l'ai eu pour travailler avec une classe interne anonyme pour créer un fil séparé pour épuiser les flux d'erreur et d'entrée.

new Thread(new Runnable(){ 
    public void run() 
    { 
     try 
     { 
      BufferedReader br = new BufferedReader(new InputStreamReader(proc.getErrorStream())); 
      String line; 
      while ((line = br.readLine())!= null) 
      { 
       System.out.println(line); 
      } 
     } 
     catch (Throwable t) 
     { 
      t.printStackTrace(); 
     } 
    } 
}).start(); 
Questions connexes