2009-05-06 7 views
1

Ich habe eine Klasse, die die Erstellung von RTF-Dokumenten verwaltet und eine Methode in dieser Klasse, die den RTF-Editor mit einer XML-Datei zur Anzeige aufruft.Runtime-Exec und ein benutzerdefinierter RTF-Editor

Alle außer einem Benutzer können auf diesen Editor ohne Probleme zugreifen. Dieser eine Benutzer stößt ständig auf ein Problem, bei dem seine Anwendung einfach hängen bleibt. Es gibt keine Fehler in irgendwelchen Protokollen. Normalerweise wird diese Art von Problem leicht identifiziert, reproduziert und korrigiert, aber ich kann es nicht für das Leben von mir reproduzieren, so dass meine Debugging-Versuche fehlschlagen.

Grundsätzlich ist der Code ist wie folgt:

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; 
} 

Der letzte Ausgang der ersten System.out ist. Wenn ich die XML-Datei nehme und diese auf einem anderen PC ausführe, wird sie ohne Probleme ausgeführt. Ich sehe keine nützliche Information in proc.getErrorStream() oder proc.getOutputStream().

Die Javadoc Dokumentation des JDK auf dieses Problem (exec hanging): Da einige nativen Plattformen nur begrenzte Puffergröße für Standard-Ein- und Ausgangsströme, Ausfall liefern prompt den Eingangsstrom oder lesen Sie den Ausgangsstrom des subprocess schreiben kann Veranlasse den Subprozess zu blockieren und sogar Deadlock.

versuche ich, diesen Strom erschöpfen, bevor sie für den Prozess warten zu beenden und das scheint nicht zu helfen, wie es nie zu diesem Punkt zu gelangen scheint (die zweite System.out wird nicht angezeigt)

Habe ich umgesetzt das falsch? Fehle ich etwas Wichtiges? Irgendwelche Ideen, wie man mehr Informationen aus dem Prozess herausholen könnte, wären großartig.

ich stecken bin ....

Antwort

2

Runtime.exec() ist eine täuschend fiese kleine Knolle mit zu arbeiten. Ich fand this article (alt, aber immer noch relevant), um ziemlich hilfreich zu sein. Sie können immer zu Seite 4 für einige sehr garbable Beispielcode springen. :-)

Auf einen Blick muss Ihr Code sowohl proc.getOutputStream() als auch proc.getErrorStream() verarbeiten, was ein guter Grund ist, diese Streams in separaten Threads zu behandeln.

+0

+1 für den Link. Dies ist ein großartiger Link und ich habe es schon zweimal von vorne nach hinten gelesen. Es war nützlich, half aber nicht ganz. Ich habe auch die proc.getOutputStream() hinzugefügt, aber immer noch kein Glück. – northpole

+0

Siehe meine bearbeitete Antwort; Sie müssen auch proc.getErrorStream() treffen. Vorzugsweise in ihren eigenen individuellen Threads. – BlairHippo

0

Ich wollte dies aktualisieren, weil die Änderung heute in Produktion ging und arbeitete. Basierend auf den Vorschlägen von BlairHippo habe ich mit einer anonymen inneren Klasse gearbeitet, um einen separaten Thread zu erstellen, der sowohl die Error- als auch die Input-Streams ausschöpft.

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(); 
Verwandte Themen