2014-09-02 75 views
0

我從我的Java應用程序(8u11)中啓動外部應用程序。但是,在Windows XP和Windows 7下,使用標準小時玻璃/微調器,應用程序無法響應UI輸入。使用Process.waitFor()時,應用程序停止響應

我將這個問題縮小到是否使用Process.waitFor()。如果我打電話給我,我會看到問題,如果我不這麼做的話。如果我退出Java應用程序,應用程序也會凍結。

我的問題是爲什麼這種情況 - 如何調用waitFor()可能會影響子進程的內部運行?我怎樣才能避免這個問題?

有問題的應用程序是LinPhone.exe,但我不認爲這個問題是特定於應用程序 - 必須有一些通用的方式來處理標準的IO等,這是我干擾通過調用waitFor ()。

我需要使用Process.waitFor(),所以我可以跟蹤應用程序何時退出。

我已經簡化了這個問題到這個SCCEE。

import java.io.BufferedReader; 
import java.io.File; 
import java.io.IOException; 
import java.io.InputStreamReader; 

public class LinphoneTest { 

    public static void main(String[] args) throws IOException, 
      InterruptedException { 
     String phoneAppPath = "C:\\Program Files\\Linphone\\bin\\linphone.exe"; 
     ProcessBuilder processBuilder = new ProcessBuilder(phoneAppPath); 
     // move up from bin/linephone.exe 
     File workingDir = new File(phoneAppPath).getParentFile() 
       .getParentFile(); 
     processBuilder.directory(workingDir); 
     processBuilder.redirectErrorStream(); 
     Process process = processBuilder.start(); 
     final BufferedReader stdout = new BufferedReader(
       new InputStreamReader(process.getInputStream())); 
     String line = null; 
     try { 
      while (((line = stdout.readLine()) != null)) { 
       System.out.println(line); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     new Thread(() -> { 
      try { 
       process.waitFor(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     }, "process wait").start(); 

     Thread.sleep(Long.MAX_VALUE); 
    } 

} 

enter image description here

+0

你是說你的過程」等待沒有反應? – 2014-09-02 15:30:07

+0

請看[當RunTime.exec()不會](http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html) 。並在後臺線程中等待。 – 2014-09-02 15:34:24

+0

謝謝。我在後臺線程上等待,因爲它最終從UI線程觸發,我從SSCCE中刪除了這個細節。我會再次添加它,看看我是否仍然可以重現該問題。 – Adam 2014-09-02 15:36:08

回答

0

總結討論,我沒有處理造成Linphone中鎖死作爲標準錯誤輸出緩衝器變得充滿尤其是Linphone中產生了大量的標準錯誤詳細輸出的標準錯誤流。 When RunTime.exec wont提供了有關從Java調用進程中涉及的陷阱的極好摘要。

也有一個錯字,我打電話叫吸氣非標準

processBuilder.redirectErrorStream(); 

時,我應該已經調用「二傳手」

processBuilder.redirectErrorStream(true);